Java反射
反射就是在运行时知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。是Java被认为是动态语言的关键。
一般在各种框架中使用。反射强大在可以越过限定符的限制。
Java是面向对象的语言,平时写的类可以看成是JDK java.lang.class 对象,他在JDK中是时刻存在的。只有在运行的时候才能知道是使用的什么类所以才有了 Class<?> 通配符
注意下面的区别
//这个是 class java.lang.Integer
System.out.println(Integer.class);
//这个是类型 int
System.out.println(int.class);
//true
System.out.println(int.class == Integer.TYPE);
任何类都是java.lang.Class的对象,(使用MAT观察内存泄漏的时候可以验证这一点)
(注意:)这里获取的是类
Class cls1 = Object.class;
Class cls2 = a.getClass();
//这里也可以使用反射表示,Class<?> cls3 = .....
Class cls3 = Class.forName("java.lang.Object");
通过反射拿到构造器的途径:
(注意:) 这里获取的是构造器
Class<?> clazz = Class.forName("com.fengwei.genericsdemo.why_use_generics_01.Person");
//带参数构造器
Constructor<Person> constructor = (Constructor<Person>) clazz.getConstructor(String.class,int.class);//
//不带参数的构造器
clazz.getConstructor();
拿到类的对象的方式如下:
注意: 这里获取的是类的对象
//使用直接new创建:
Person person = new Person();
//使用上面反射中构造器,这样获取构造函数也必须是public类型
Person person = constructor.newInstance("Sam",18);
//不能这样拿
Person person1 = (Person) clazz.newInstance("sam",18);
//只能这么拿
Person person1 = (Person) clazz.newInstance();
person1.setAge(19);
System.out.println(" age:" + person1.getAge());
####这里用来获取类的方法:
Method[] methods = clazz.getMethods();
for (Method m : methods) {
System.out.println(" Method :" + m.getName()+"()");
}
-------------------------------------------------------------
打印出来的结果如下:
Method :getName()
Method :setName()
Method :getAge()
Method :setAge()
Method :wait()
Method :wait()
Method :wait()
Method :equals()
Method :toString()
Method :hashCode()
Method :getClass()
Method :notify()
Method :notifyAll()
获取从父类继承来的所有方法,自己的私有和保护方法是不能
获取某个类中的所有的函数 包括 私有 保护 公共函数
methods = clazz.getDeclaredMethods();
--------------------------------------------------------
运行结果:
Method :getName()
Method :setName()
Method :setAge()
Method :protactMethod()
Method :privateMethod()
Method :getAge()
拿具体某一个方法,没有参数的时候不传 这种形式也可以拿到私有的方法:
Method method = clazz.getDeclaredMethod("setName",String.class);
如果拿到方法以后 我们该怎么执行昵?
Person person2 = (Person) clazz.newInstance();
Method method = clazz.getDeclaredMethod("privateMethod",String.class);
//在执行私有方法的时候,要使用这个设置为true , public方法是不需要使用的
method.setAccessible(true);
//第一个参数用类对象也可以
method.invoke(person2,"");
这样书写为什么不能访问私有的静态方法?
Method staticMethod = clazz.getDeclaredMethod("privateStaticMethod",new Class[]{String.class});
method.setAccessible(true);
staticMethod.invoke(clazz,"aaa");
获取自己的所有的所有的私有 静态 公有方法:
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println("get All Field: " + field.getName());
}
得到特定变量的值:
Field field = clazz.getDeclaredField("name");
Constructor<Person> constructorField = (Constructor<Person>) clazz.getConstructor(String.class,int.class);
Person person3= constructorField.newInstance("sam",19);
String name = (String) field.get(person3);
System.out.println("name :" + name);
修改age的值:
field = clazz.getDeclaredField("age");
field.setAccessible(true);
field.set(person3,30);
System.out.println("get age : " + person3.getAge());