Java中反射
类加载的三种机制
1、通过getClass
People p =new People();
Class c = p.getClass();
2、People.class
Class c1=People.class;
3、Class.forName("tianpo.com.demo.People");
Class c2=Class.forName("tianpo.com.demo.People");
对象比较
//比较内存地址,类加载器只会创建一次
System.out.println(c==c2);
//比较的是属性值
System.out.println(c.equals(c2));
反射
其实就是把class文件进行结构拆解:
- 构造函数(有参/无参)
- 成员变量(属性)
- 方法
反射构造函数
Class c =Class.forName("tianpo.com.demo.People");
## 有参
Constructor constructor=c.getConstructor(String.class,int.class);
## 无参
Constructor constructor1=c.getConstructor();
Object obj=constructor.newInstance("dd",22);
People p =(People)obj;
System.out.println(p);
暴力反射(不建议使用,破坏了封装性、安全性)
如果方法是 private修饰的,当你用反射去访问的时候
setAccessible(true); 之后才能访问;另外从某方面说,选择它可以提高反射的速度,因为不需要再通过语言检查了。
//构造函数是私有的
private People(String name, int age) {
super();
this.name = name;
this.age = age;
}
Class c =Class.forName("tianpo.com.demo.People");
Constructor constructor=c.getDeclaredConstructor(String.class,int.class);
//暴力反射,取消运行时权限检查
constructor.setAccessible(true);
Object obj=constructor.newInstance("dd",22);
System.out.println(obj);
动态调用内部方法
Class c = Class.forName("tianpo.com.demo.People");
Constructor con = c.getConstructor();
Method m =c.getMethod("eat");
Object obj1=con.newInstance();
m.invoke(obj1);
获取所有成员变量
Class c = Class.forName("tianpo.com.demo.People");
# 获取所有public类型的成员变量
Field[] fs=c.getFields();
# 获取所有private
Field[] fs1=c.getDeclaredFields();
for(Field field:fs){
System.out.println(field);
}
Field field=c.getDeclaredField("age");
Constructor con = c.getConstructor();
Method m =c.getMethod("eat");
Object obj1=con.newInstance();
//动态赋值
field.set(obj1,18);
System.out.println(obj1);
反射的泛型擦除
ArrayList<String> array = new ArrayList<String>();
array.add("张三");
// 编译时会做类型检查
//array.add(10);
Class c = array.getClass();
Method m = c.getMethod("add",Object.class);
m.invoke(array,10);
m.invoke(array,13.8);
System.out.println(array);
通过配置执行调用
创建一个config.properties
className = tianpo.com.demo.People
methodName = eat
className = tianpo.com.demo.Student
methodName = Study
className = tianpo.com.demo.Worker
methodName = Work
反射调用
FileReader rd = new FileReader("config.properties");
Properties pro = new Properties();
pro.load(rd);
rd.close();
String className = pro.getProperty("className");
String methodName = pro.getProperty("methodName");
Class c =Class.forName(className);
Method m = c.getMethod(methodName);
Object obj=c.newInstance();
m.invoke(obj);