目录
实际应用示例:利用反射实现只修改配置文件,实现调用某个类的类中方法
反射概述
- 允许程序在运行时来进行自我检查并且对内部的成员进行操作
- 反射主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描素行为的状态和相关的语义
反射机制的作用
- 在运行时判断任意一个对象所属的类
- 在运行时获取类的对象
- 在运行时访问Java对象的属性,方法,构造方法等
Java.lang.reflect类库里面主要的类
- Filed:表示类中的成员变量
- Method:表示类中的方法
- Constructor:表示类中的构造方法
- Array:该类提供了动态创建数组和访问数组元素的静态方法
反射三种获取方式
- Object->getCLass()
- 任何数据类型都有一个"静态"的Class属性
- 通过Class 类的静态方法:forName(String className)
public static void main(String[] args) throws Exception{
// 1.全类名方式获取:将字节码文件加载进内存,返回Class对象,多用于配置文件,读取文件加载累
Class cls1 = Class.forName("com.mayi.Person");
// 2.类名.Class:通过类名的class属性获取,多用于参数传递
Class cls2 = Person.class;
// 3.对象.getClass():Object类中的方法,多用于对象的获取字节码方式
Class cls3 = new Person().getClass();
// 输出结果相等:同一个字节码文件(.class)在一次程序的运行过程中,只会被加载一次,
// 不论通过哪一种方式获取的Class对象都是同一个
System.out.println(cls1 == cls2);
System.out.println(cls1 == cls3);
}
获取成员变量
public static void main(String[] args) throws Exception{
Person person = new Person();
person.setAge("11");
person.setName("12");
person.setSex("男");
Class<Person> personClass = Person.class;
// 获取所有public修饰的成员变量
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
// 获取指定的成员变量的值
Field field = personClass.getField("sex");
System.out.println(field.getName()+":"+field.get(person));
// 重新设置值
field.set(person,"女");
System.out.println(field.getName()+":"+field.get(person));
// 获取所有成员变量,不考虑修饰符
Field[] declaredFields = personClass.getDeclaredFields();
for (Field field1 : declaredFields) {
System.out.println(field1);
}
Field ageField = personClass.getDeclaredField("age");
// 打印异常 java.lang.IllegalAccessException:
// Class com.mayi.ReflectDemo can not access a member of class com.mayi.Person with modifiers "private"
System.out.println(ageField.get(person));
// 暴力反射
ageField.setAccessible(true);
System.out.println(ageField.get(person)); //11
}
获取构造器
public static void main(String[] args) throws Exception{
Class<Person> personClass = Person.class;
Constructor<Person> constructor = personClass.getConstructor(String.class,String.class,String.class);
Person person = constructor.newInstance("小红", "22", "女");
System.out.println(person);
// 空参构造器的创建对象方法
Person person1 = personClass.newInstance();
System.out.println(person1);
}
获取方法
public static void main(String[] args) throws Exception{
Person person = new Person();
Class pClass = new Person().getClass();
Method eat = pClass.getMethod("eat");
// invoke 执行方法
eat.invoke(person);
Method eatFood = pClass.getMethod("eat",String.class);
eatFood.invoke(person,"馒头");
// 获取所有方法
Method[] methods = pClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
}
实际应用示例:利用反射实现只修改配置文件,实现调用某个类的类中方法
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
InputStream inputStream = ReflectTest.class.getClassLoader().getResourceAsStream("pro.properties");
// 加载配置文件
properties.load(inputStream);
String className = properties.getProperty("className");
String methodName = properties.getProperty("methodName");
Class cls = Class.forName(className);
// 创建实例
Object obj = cls.newInstance();
// 获取方法
Method method = cls.getMethod(methodName);
// 执行方法
method.invoke(obj);
}