最常见的两个作用
- 根据类名创建实例(类名可以从配置文件读取, 不用new, 达到解耦)
- 用Method.invoke() 执行方法
常见Api
-
获取Class类的方法
package com.aiwenbin.reflection; public class ClassDemo01 { public static void main(String[] args) { /** * 1. 获取TypeDemo01类的三种方法 */ try { // 1. 通过Class.forName()获取 Class clazz1 = Class.forName("com.aiwenbin.reflection.TypeDemo01"); System.out.println(clazz1); // 2. 通过类名.class获取 Class clazz2 = TypeDemo01.class; System.out.println(clazz2); // 3. 通过对象.getClass()获取 TypeDemo01 typeDemo01 = new TypeDemo01(); Class clazz3 = typeDemo01.getClass(); System.out.println(clazz3); /** * 会发现这三种拿到的值,都是相等的。 * 可以得出一个结论,在当前的jdk运行环境中,同一个.class字节码文件只被加载一次, * 被加载之后,第二次再去拿的话,就会直接引用之前的,所以是一样的。 */ System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
问题: 如何比较两个Class类是否相同?(可以在评论区说出你的答案)
- Class类的作用
- 获取类名
- 获取成员变量
- 获取成员方法
- 获取构造方法
package com.aiwenbin.reflection;
import java.lang.reflect.Field;
public class ClassDemo02 {
public static void main(String[] args) {
/**
* Class 类常见的用法
*/
Class clazz = TypeDemo01.class;
// 1. 获取类的名字
String clazzName = clazz.getName();
System.out.println(clazzName);
System.out.println("----");
// 2. 获取公开的成员变量
Field[] fields = clazz.getFields();
for(Field field : fields) {
System.out.println(field);
}
System.out.println("----");
// 3. 获取全部的成员变量
Field[] declaredFields = clazz.getDeclaredFields();
for (int i = 0; i < declaredFields.length; i++) {
System.out.println(declaredFields[i]);
}
System.out.println("----");
// 4. 获取注解
// 5. 获取构造方法
}
}
常见应用
-
在不改动Java代码的情况下, 创建任意一个对象并执行任意一个方法
设置两个类:
package com.aiwenbin.reflection.peoject01; public class P { public void aaa() { System.out.println("这是p下的aaaa"); } }
和;
package com.aiwenbin.reflection.peoject01; public class Student { private String name = "默认的名字"; public Student() { } public Student(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void printName() { System.out.println(name); } }
application.properties配置文件内容:
1className=reflect.P #要创建的类的全类名 2methdName=aaa #要执行的方法
核心文件:”
package com.aiwenbin.reflection.peoject01; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.sql.Ref; import java.util.Properties; public class ReflectTest { public static void main(String[] args) { // 1. 加载并解析配置文件 Properties properties = new Properties(); ClassLoader classLoader = ReflectTest.class.getClassLoader(); InputStream resourceAsStream = classLoader.getResourceAsStream("application.properties"); try { properties.load(resourceAsStream); String className = properties.getProperty("className"); String methName = properties.getProperty("methName"); Class cls = Class.forName(className); Object o = cls.newInstance(); Method method = cls.getMethod(methName); method.invoke(o); } catch (Exception e) { e.printStackTrace(); } } }
测试:
修改一下一下配置文件:
1className=reflect.Student 2methdName=printName
就可以看到这种效果了