Fork me on GitHub

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文件进行结构拆解:

  1. 构造函数(有参/无参)
  2. 成员变量(属性)
  3. 方法

反射构造函数

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);
posted @ 2018-06-23 18:11  迁梦余光  阅读(163)  评论(0编辑  收藏  举报