反射
将类的各个组成(属性、构造函数、方法等)部分封装成其他对象,这就是反射机制
反射的优点
-
可以在程序运行的时候创建对象
-
可以实现代码解耦
获取字节码对象(Class)的三种方式
- 通过Class.forName(“全类名”)方法; 多用于读取配置文件,根据配置文件的信息创建对象
- 通过类名.class获取 多作为参数传递
- 通过对象.getClass()获取 用于有对象的时候获取字节码对象
Class对象只会被加载一次
Class对象功能
-
获取
-
获取属性
Field[] getFields() : 获取所有public类型的属性 Field getField(String name) : 获取指定的public类型的属性 Field[] getDeclaredFields() : 获取所有的属性 Field etDeclaredField(String name) : 获取指定的属性
-
获取对构造方法
Constructor getConstructor(Class<T> ..);
创建对象迪要使用Constructor的newInstance()方法,参数为构造器定义的参数列表
Class对象中的newInstance可以快速通过无参构造器创建对象
-
获取成员方法
Method getMethod(对象引用,参数列表)
Method[] getMethods(对象) 获取所有public 修饰的方法,同属性类似还有获取所有方法,不做阐述
。。。
-
代码示例
反射加配置文件实现一个简单地解耦
public class Demo {
public static void main(String[] args) throws Exception {
ClassLoader loader = Demo.class.getClassLoader();
InputStream resourceAsStream = loader.getResourceAsStream("a.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
Class clazz = Class.forName(properties.getProperty("name"));
Object o = clazz.newInstance();
Method method = clazz.getMethod(properties.getProperty("method"));
method.invoke(o);
}
}
a.properties文件中
name=com.wah.fundation.domain.Student
method=sleep
Person类和Student类中
private String name;
private Integer age;
public void sleep(){
System.out.println("person/student打印了一句话");//person类中写person,student类中写student
}
最后只需修改a.properties配置文件就能够控制代码的执行