#|头歌Educoder——Java高级特性 - Java反射


文章目录

  • 第1关:了解 Class 对象
    • 任务描述
    • 相关知识
      • Class 对象
      • 三种获取Class类型的实例的方法
      • 三种方法获取的 Class 对象之间的区别
    • 编程要求
    • 测试说明
    • 代码样例
      • Reflect_stu.java
      • Reflect_run.java
      • Person.java
  • 第2关:利用反射分析类的能力
    • 任务描述
    • 相关知识
      • 反射的基本概念
      • Class 对象与反射之间的关系
      • Class 的类结构
      • 利用反射分析类的能力
    • 编程要求
    • 测试说明
    • 代码样例
      • Reflect_stu.java
      • Reflect_run.java
      • Person.java
  • 第3关:在运行时使用反射分析对象
    • 任务描述
    • 相关知识
      • 如何通过 `Field` 类的 `get` 方法获取对象域
      • 如何绕过 `Java` 安全访问控制获取私有对象域
      • 获取对象域时数值类型如何处理
    • 编程要求
    • 测试说明
    • 代码示例
      • Reflect_stu.java
      • Reflect_run.java
  • 第4关:利用反射进行方法调用
    • 任务描述
    • 相关知识
      • 如何通过反射创建对象
      • 如何通过反射调用对象方法
    • 编程要求
    • 测试说明
    • 代码示例
      • Reflect_stu.java
      • Reflect_run.java

第1关:了解 Class 对象 任务描述 本关任务:实现获取Class对象的三种方式
相关知识 为了完成本关任务,你需要掌握:
  1. Class对象;
  2. 三种获取Class类型的实例的方法;
    1. 通过Object类中的getClass()方法;
    2. 通过静态方法Class.forName("全类名")
    3. 通过类字面常量Class.class
  3. 三种方法获取的Class对象之间的区别。
Class 对象
  1. 在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识(RTTI)。这个信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。保存这些信息的类被称为Class,可以通过专门的Java类访问这些信息。
  2. Class类的实例表示正在运行的Java应用程序中的类和接口。其中枚举是一种特殊的类,注释是一种特殊的接口。每个数组属于被映射为Class对象的一个类,所有具有相同元素类型和维数的数组都共享该Class对象基本的Java类型(booleanbytecharshortintlongfloatdouble)和关键字void也表示为Class对象。
  3. Class对象就是用来创建类的所有的”常规”对象的。每个类都有一个Class对象,每当编写一个并且编译了一个新类,就会产生一个Class对象(保存在体同名的 .class 文件中)。
  4. Class没有公共构造方法。Class对象是在加载类时由Java虚拟机以及通过调用类加载器中的defineClass方法自动构造的。
三种获取Class类型的实例的方法
方法1:通过Object类中的getClass()方法返回一个Class类型的实例
示例如下:
Person person = new Person(); Class clazz = person.getClass();

【#|头歌Educoder——Java高级特性 - Java反射】方法2:通过静态方法Class.forName("全类名")获取类名对应的Class对象
Class.forName()方法原型:
public static Class forName(String className) throws ClassNotFoundException

若无法根据类路径className找到对应的 .class 文件会抛出 ClassNotFoundException异常,因此使用forName()方法需要捕获异常或向上抛出异常。
示例如下:
Class clazz = null; String className = "step1.Person"; try { clazz = Class.forName(className); } catch(ClassNotFoundException e) { }

方法3:通过类字面常量Class.class获取
示例如下:
Class clazz = Person.class;

该方法不仅更简单,而且更安全,因为它在编译时就会受到检查(因此不需要置于try语句块中)。并且它根除了对forName()方法的调用,所以更高效。
三种方法获取的 Class 对象之间的区别
每个类都有一个Class对象,因此对于某个类使用三种方式获取的 Class对象都是相等。
编程要求 请仔细阅读右侧代码,结合相关知识,在Begin-End 区域内进行代码补充,完成三个方法getPersonClass1()getPersonClass2()getPersonClass3()的代码编写,要求分别使用三种方式获取Person类的Class对象并返回。 注意:无需修改main()方法的输出内容。
测试说明 平台会对你编写的代码进行测试:
预期输出:
通过Object 类中的 getClass() 获取的 Class 对象为:class step1.Person
通过静态方法 Class.forName() 获取的 Class 对象为:class step1.Person
通过类字面常量获取 Class 的对象为:class step1.Person
开始你的任务吧,祝你成功!
代码样例 Reflect_stu.java
package step1; /** * 学员任务文件 */ public class Reflect_stu { public static void main(String[] args) { System.out.println("通过Object 类中的 getClass() 获取的 Class 对象为:" + getPersonClass1()); System.out.println("通过静态方法 Class.forName() 获取的 Class 对象为:" + getPersonClass2()); System.out.println("通过类字面常量获取 Class 的对象为:" + getPersonClass3()); } /** * 通过 Object 类中的 getClass() 获取的 Class 对象 * * @return */ public static Class getPersonClass1() { /********** Begin *********/ Person person = new Person(); Class clazz1 = person.getClass(); return clazz1; /********** End *********/ } /** * 通过静态方法 Class.forName() 获取的 Class 对象 * * 注意:Person 类的全路径为: step1.Person * * @return */ public static Class getPersonClass2() { /********** Begin *********/ String className = "step1.Person"; Class clazz2 = null; try { clazz2 = Class.forName(className); } catch (ClassNotFoundException e) { }return clazz2; /********** End *********/ } /** * 通过类字面常量获取 Class 的对象 * * @return */ public static Class getPersonClass3() { /********** Begin *********/ Class clazz3 = Person.class; return clazz3; /********** End *********/ } }

Reflect_run.java
package step1; /** * 评测执行文件 */public class Reflect_run {public static void main(String[] args) { //Class clazz1 = Person.class; 2、通过对象的getClass()方法返回一个Class类型的实例 //Person person = new Person(); //Class clazz2 = person.getClass(); 3、通过静态方法Class.forName()获取类名对应的Class对象 //Class clazz3 = null; //try { //clazz3 = Class.forName("step1.Person"); //} catch (ClassNotFoundException e) { //e.printStackTrace(); //} // //// 使用 "==" 进行比较 clazz1 与 clazz2 的关系 //System.out.println(clazz1 == clazz2); //// 使用 "==" 进行比较 clazz2 与 clazz3 的关系 //System.out.println(clazz2 == clazz3); System.out.println("通过Object 类中的 getClass() 获取的 Class 对象为:" + getPersonClass1()); System.out.println("通过静态方法 Class.forName() 获取的 Class 对象为:" + getPersonClass2()); System.out.println("通过类字面常量获取 Class 的对象为:" + getPersonClass3()); }/** * 通过 Object 类中的 getClass() 获取的 Class 对象 * * @return */ public static Class getPersonClass1() { return new Person().getClass(); }/** * 通过静态方法 Class.forName() 获取的 Class 对象 * * @return */ public static Class getPersonClass2() { Class clazz = null; try { clazz = Class.forName("step1.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } return clazz; }/** * 通过类字面常量获取 Class 的对象 * * @return */ public static Class getPersonClass3() { return Person.class; } }

Person.java
package step1; public class Person {}

第2关:利用反射分析类的能力 任务描述 本关任务:利用反射获取Apple类的的所有的方法和构造器签名,以及全部域名。
相关知识 为了完成本关任务,你需要回顾上节所学Class对象的相关知识, 以及需要掌握以下知识:
  1. 反射的基本概念;
  2. Class对象与反射之间的关系;
  3. Class的类结构;
  4. 利用反射分析类的能力。
反射的基本概念
反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
Class 对象与反射之间的关系
Java 反射机制允许程序在运行时取得任何一个已知名称的Class 的内部信息,包括其 modifiers(修饰符)、fields(属性),methods(方法)等,并可于运行时改变 fields 内容或调用 methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!
Class 的类结构
java.lang.reflect包中有三个类FieldMethodConstructor分别用于描述类的域、方法和构造器。Class类中的getFields()getMethods()getConstructors()方法将分别返回类提供的 public 域、方法和构造器,其中包括超类的共有成员。Class类中的getDeclareFields()getDeclareMethods()getDeclareConstructors()方法将分别返回类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。
如:
public Field[] getFields() throws SecurityException public Method[] getMethods() throws SecurityException public Constructor[] getConstructors() throws SecurityException

利用反射分析类的能力
通过获取某个类的Class对象,并通过Class类的 getFields()getMethods()getConstructors()获得所有域、方法和构造器。
示例:
class Person { public String name; String sex; protected String height; private int age; public Person() { } private Person(String name) { this.name = name; } public Person(String name, String sex, String height, int age) { ...省略 } } public static void main(String[] args) { Person person = new Person(); printConstructors(person.getClass()); } public static void printConstructors(Class clazz) { Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { String name = constructor.getName(); System.out.print(""); String modifiers = Modifier.toString(constructor.getModifiers()); if (modifiers.length() > 0) { System.out.print(modifiers + " "); } System.out.print(name + "("); Class[] paramTypes = constructor.getParameterTypes(); for (int j = 0; j < paramTypes.length; ++j) { if (j > 0) { System.out.print(","); } System.out.print(paramTypes[j].getName()); } System.out.println("); "); } }

输出结果:
public Person();
public Person(java.lang.String,java.lang.String,java.lang.String,int);
编程要求 请仔细阅读右侧代码,结合相关知识,在Begin-End 区域内进行代码补充,打印Apple类的所有public 域、方法和构造器。已分别提供了方法声明printConstructorsprintFieldsprintMethods,请将代码补充完整,且按照打印格式要求输出。
提示:
  1. Method.getReturnType()可以获得方法的返回类型。
  2. 打印方法或域的修饰符可以调用提供的printModifiers()方法
  3. 打印方法的参数可以调用提供的printParamTypes()方法
  4. FieldgetType方法可以获得域类型、getName方法可以获得域的名称
测试说明 预期输出:
private java.lang.String name;
public step2.Apple();
public step2.Apple(java.lang.String);
public void setName(java.lang.String);
平台会对你编写的代码进行测试。
开始你的任务吧,祝你成功!
代码样例 Reflect_stu.java
package step2; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; class Apple { private String name; public Apple() { } public Apple(String name) { } public void setName(String name) { this.name = name; } }public class Reflect_stu { public static void main(String[] args) { // 请根据提供的 classPath 获取 step2.Apple 的 Class 对象, 请使用 Class.forName() 方法, 注意捕获异常 // 通关之后,你也可以修改 clasapath 为其他类路径,分析某个类的能力, 例如: java.util.Date String classPath = "step2.Apple"; Class clazz = null; /********** Begin *********/ try { clazz = Class.forName(classPath); } catch (ClassNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }/********** End *********/ printFields(clazz); printConstructors(clazz); printMethods(clazz); } /** * 请打印类的每个域,输出格式为:修饰符 类型 变量名; * * @param clazz */ public static void printFields(Class clazz) { /********** Begin *********/ try { Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.print(Modifier.toString(field.getModifiers()) + " "); System.out.print(field.getType().getTypeName() + " "); System.out.println(field.getName() + "; "); } } catch (Exception e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }/********** End *********/ } /** * 打印构造函数,输出格式为:修饰符 方法名称(参数) * * @param clazz */ public static void printConstructors(Class clazz) { Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { Class[] paramTypes = null; /********** Begin *********/paramTypes = constructor.getParameterTypes(); System.out.print(Modifier.toString(constructor.getModifiers()) + " "); System.out.print(constructor.getName() + "("); /********** End *********/ printParamTypes(paramTypes); } } /** * 请针对每个方法打印其签名,格式为:修饰符 返回值类型 方法名称(参数); * * @param clazz */ public static void printMethods(Class clazz) { Method[] methos = clazz.getDeclaredMethods(); for (Method method : methos) { Class[] paramTypes = null; /********** Begin *********/paramTypes = method.getParameterTypes(); System.out.print(Modifier.toString(method.getModifiers()) + " " + method.getReturnType().getName() + " " + method.getName() + "("); /********** End *********/ printParamTypes(paramTypes); } } /** * 打印方法参数 * * @param paramTypes */ private static void printParamTypes(Class[] paramTypes) { for (int j = 0; j < paramTypes.length; ++j) { if (j > 0) { System.out.print(","); } System.out.print(paramTypes[j].getName()); } System.out.println("); "); }}

Reflect_run.java
package step2; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class Reflect_run {public static void main(String[] args) { // 请根据提供的 classPath 获取 step2.Apple 的 Class 对象 String classPath = "step2.Apple"; Class clazz = null; try { clazz = Class.forName(classPath); } catch (ClassNotFoundException e) { e.printStackTrace(); } printConstructors(clazz); printFields(clazz); printMethods(clazz); }public static void printConstructors(Class clazz) { Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { String name = constructor.getName(); printModifiers(clazz); System.out.print(name + "("); Class[] paramTypes = constructor.getParameterTypes(); printParamTypes(paramTypes); } }private static void printModifiers(Class clazz) { System.out.print(""); String modifiers = Modifier.toString(clazz.getModifiers()); if (modifiers.length() > 0) { System.out.print(modifiers + " "); } }public static void printMethods(Class clazz) { Method[] methos = clazz.getDeclaredMethods(); for (Method method : methos) { Class returnType = method.getReturnType(); String name = method.getName(); printModifiers(clazz); System.out.print(returnType.getName() + " " + name + "("); Class[] paramTypes = method.getParameterTypes(); printParamTypes(paramTypes); } }private static void printParamTypes(Class[] paramTypes) { for (int j = 0; j < paramTypes.length; ++j) { if (j > 0) { System.out.print(","); } System.out.print(paramTypes[j].getName()); } System.out.println("); "); }public static void printFields(Class clazz) { Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { Class type = field.getType(); String name = field.getName(); printModifiers(clazz); System.out.println(type.getName() + " " + name + "; "); } } }

Person.java
package step2; public class Person {public String name; protected String height; String sex; private int age; public Person() {}public Person(String name) { this.name = name; }public Person(String name, String sex, String height, int age) { this.name = name; this.sex = sex; this.height = height; this.age = age; }public String getSex() { return sex; }public void setSex(String sex) { this.sex = sex; }public String getHeight() { return height; }public void setHeight(String height) { this.height = height; }public int getAge() { return age; }public void setAge(int age) { this.age = age; } }

第3关:在运行时使用反射分析对象 任务描述 本关任务:完成一个可供任意类使用的通用toString(Object)方法。
相关知识 为了完成本任务,你需要掌握:
  1. 如何通过Field类的get方法获取对象域;
  2. 如何绕过 Java 安全访问控制获取私有对象域;
  3. 获取对象域时数值类型如何处理。
如何通过 Field 类的 get 方法获取对象域
利用反射机制可以查看在编译时还不清楚的对象域。而查看对象域的关键方法就是Field类中的get方法。
Object get(Object obj) 返回指定对象上此Field表示字段的值。
如果f是一个Field类型的对象(例如,通过getDeclaredFields() 得到的对象),obj是一个包含f域的类的对象, 那么f.get(obj)将返回一个对象,其值为obj域的当前值。如此就可以在运行时获得对象的域。
示例:
class Person { public Integer weight; private Integer age; private double height; // 省略构造器、setter 和 getter 方法 } public void test() { Person person = new Person(123, 19); Class clazz = person.getClass(); Field field = clazz.getDeclaredField("weight"); Object name = field.get(person); System.out.println(name); // 其打印结果为: "123" }

如何绕过 Java 安全访问控制获取私有对象域
那如果要获取对象的私有域呢,例如,要获取Perso小明的年龄呢,直接修改上面示例为getDeclaredField("age")可以吗。答案是,不行,因为age是一个私有域,所以get方法会抛出一个 IllegalAccessException异常。
只有利用get方法才能得到可访问域的值。除非拥有访问权限,Java 安全机制只允许查看任意对象有哪些域,而不允许读取它们的值。
反射机制的默认行为受限于 Java 的访问控制。然而,如果一个 Java程序没有收到安全管理器的控制,就可以覆盖访问控制。调用 FieldMethodConstructor对象的setAccessible 方法可以突破这种限制。
示例:
public void test() { Person person = new Person(123, 19, 175); Class clazz = person.getClass(); Field field = clazz.getDeclaredField("age"); // 获取私有域的访问权限 field.setAccessible(true); Object name = field.get(person); System.out.println(name); // 其打印结果为: "19" }

获取对象域时数值类型如何处理
Object get(Object obj) 返回指定对象上此Field表示字段的值。
get方法还有一个要解决的问题。name域是一个String,因此可以作为Object返回。但是,如果要查看height域,它属于double类型,而 Java 中数值类型不是对象。因此要使用Field的其他 getXXX() 方法。反射机制会自动的将这个域值打包到相应的对象包装器中。
double getDouble(Object obj) 获取double类型或另一个通过扩展转换可以转换为double类型的基本类型的静态或实例字段的值。
float getFloat(Object obj) 获取float类型或另一个通过扩展转换可以转换为float类型的基本类型的静态或实例字段的值。
Type getGenericType() 返回一个Tpye对象,它表示此Field对象所表示字段的声明类型。
int getInt(Object obj) 获取int类型或另一个通过扩展转换可以转换为int类型的基本类型的静态或实例字段的值。
long getLong(Object obj) 获取long类型或另一个通过扩展转换可以转换为long类型的基本类型的静态或实例字段的值。
编程要求 请仔细阅读右侧代码,结合相关知识,在Begin-End 区域内进行代码补充,完成通用toString()方法。
提示:
快速设置访问权限: ``AccessibleObject.setAccessible(fields, true); `` 获得所有域:``Class.getDeclaredFields()``

测试说明 平台会对你编写的代码进行测试。
示例:
public static void toString(Object obj) { // 请完成代码 } public static void main(String[] args) { Person person = new Person(123, 19, 175); toString(person); }

预期输出: [weight=[value=https://www.it610.com/article/123],age=[value=19],height=[value=175.0]]
开始你的任务吧,祝你成功!
代码示例 Reflect_stu.java
package step3; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class Reflect_stu { public static String toString(Object obj) { Class cl = obj.getClass(); String r = ""; r += "["; // 请获取所有 Field 并设置访问权限为 true /********** Begin *********/ Field[] fields = null; fields = cl.getDeclaredFields(); AccessibleObject.setAccessible(fields, true); /********** End *********/ for (Field f : fields) { // 此处 if,逻辑为判断 Field 域是否为非静态域 if (!Modifier.isStatic(f.getModifiers())) { if (!r.endsWith("[")) r += ","; r += f.getName() + "="; try { // 请获取域的类型及值 /********** Begin *********/Class t = null; Object val = null; t = f.getType(); val = f.get(obj); /********** End *********/ // isPrimitive() 用于判断是否为基本数据类型,若为基础数据类型直接拼接,否则递归调用 toString 方法 if (t.isPrimitive()) r += val; else r += toString(val); } catch (Exception e) { e.printStackTrace(); } } } r += "]"; return r; } public static void main(String[] args) { Person person = new Person(88, 19, 175); System.out.println(toString(person)); } }class Person { public Integer weight; private Integer age; private Double height; public Person(Integer weight, Integer age, double height) { this.weight = weight; this.age = age; this.height = height; } }

Reflect_run.java
package step3; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class Reflect_run {public static String toString(Object obj) { Class cl = obj.getClass(); String r = ""; r += "["; Field[] fields = cl.getDeclaredFields(); AccessibleObject.setAccessible(fields, true); for (Field f : fields) { if (!Modifier.isStatic(f.getModifiers())) { if (!r.endsWith("[")) r += ","; r += f.getName() + "="; try { Class t = f.getType(); Object val = f.get(obj); if (t.isPrimitive()) r += val; else r += toString(val); } catch (Exception e) { e.printStackTrace(); } } } r += "]"; return r; }public static void main(String[] args) { Person person = new Person(88, 19, 175); System.out.println(toString(person)); }}

第4关:利用反射进行方法调用 任务描述 本关任务:利用反射创建对象并调用其方法。
相关知识 为了完成本关任务,你需要掌握:
  1. 如何通过反射创建对象;
  2. 如何通过反射调用对象方法。
如何通过反射创建对象
反射创建类对象主要有两种方式,通过Class对象的newInstance()方法、通过Constructor对象的 newInstance()方法。
  1. 第一种:通过Class对象的newInstance()方法。
    Class clazz = Apple.class; Apple apple = (Apple)clazz.newInstance();

  2. 第二种:通过Constructor对象的newInstance()方法
    Class clazz = Apple.class; Constructor constructor = clazz.getConstructor(); Apple apple = (Apple)constructor.newInstance();

通过Constructor对象创建类对象可以选择特定构造方法,而通过 Class对象则只能使用默认的无参数构造方法。
示例:(调用有参构造方法进行类对象的初始化)
Class clz = Apple.class; Constructor constructor = clz.getConstructor(String.class, int.class); Apple apple = (Apple)constructor.newInstance("红富士", 15);

如何通过反射调用对象方法
利用Methodinvoke方法可以调用执行对象obj的方法
More ActionsObjectinvoke(Object obj,Object… args) 对带有指定参数的指定对象调用由此Method对象表示的底层方法。
参数: obj 表示要调用的Method方法对象。 args 表示要调用的方法的参数,是可变长参数类型。
示例:
// 获取类的 Class 对象实例 Class clz = Class.forName("Apple"); // 根据 Class 对象实例获取 Constructor 对象 Constructor appleConstructor = clz.getConstructor(); // 使用 Constructor 对象的 newInstance 方法获取反射类对象 Object appleObj = appleConstructor.newInstance(); // 而如果要调用某一个方法,则需要经过下面的步骤: // 1、获取方法的 Method 对象 Method setPriceMethod = clz.getMethod("setPrice", int.class); // 2、用 invoke 方法调用方法 setPriceMethod.invoke(appleObj, 14); class Apple { public void setPrice(int price) { //省略 } // 省略 }

编程要求 请仔细阅读右侧代码,结合相关知识,在Begin-End 区域内进行代码补充,使用反射调用 Apple 类的 setPrice()方法,设置苹果价格为 14,并打印价格。接着还要用反射去调用getTotal方法获取单价为 20,数量 24 的总金额并打印。
测试说明 预期输出:
14.0
480.0
平台会对你编写的代码进行测试。
开始你的任务吧,祝你成功!
代码示例 Reflect_stu.java
package step4; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Reflect_stu { public static void main(String[] args) throws InvocationTargetException { // 使用反射调用 Class clazz = null; try { clazz = Class.forName("step4.Apple"); /********** Begin *********/ Constructor cons = clazz.getConstructor(); Apple apple = (Apple) cons.newInstance(); Method method = clazz.getMethod("setPrice", double.class); method.invoke(apple, 14); Method getPrice = clazz.getMethod("getPrice"); System.out.println(getPrice.invoke(apple)); Method getTotal = clazz.getMethod("getTotal", double.class, int.class); System.out.println(getTotal.invoke(apple, 20, 24)); /********** End *********/ } catch (Exception e) { e.printStackTrace(); } }}class Apple { private double price; private int count; public Apple() { } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public double getTotal(double price, int count) { return price * count; } }

Reflect_run.java
package step4; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Reflect_run { public static void main(String[] args) throws InvocationTargetException { //使用反射调用 Class clazz = null; try { clazz = Class.forName("step4.Apple"); Method setPriceMethod = clazz.getMethod("setPrice", double.class); Constructor appleConstructor = clazz.getConstructor(); Object apple = appleConstructor.newInstance(); setPriceMethod.invoke(apple, 20); Method getPriceMethod = clazz.getMethod("getPrice"); System.out.println(getPriceMethod.invoke(apple)); Method getTotal = clazz.getMethod("getTotal", double.class, int.class); System.out.println(getTotal.invoke(apple, 20, 24)); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException e) { e.printStackTrace(); } } }

    推荐阅读