1. 什么是反射
反射是java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法
2. 一切反射相关的代码都从获得类对象开始
2.1 getClass()方法,这是一个Object类定义的方法,涉及到强转,用通配符表示泛型可以避免强转。
2.2 类名.class;返回类型为Class。
2.3 Class类的静态方法——Class.forName(String className),参数为类的全限定名。
注意:
ClassNotFoundException(类名错|少jar包)
同一类的、类对象只会创建一个
3. 反射三大作用(java.lang.reflect.*)
3.1 实例化对象
c.newInstance()
/**
* ~~~~~~~~~~~~~~~~~~~利用反射进行实例化~~~~~~~~~~~~~~~~~~~~~
* 能够获取到Student.Class
* 如何通过Student.Class拿到Student的一个实例?
*
* 反射的好处
* 能够见未知的类进行实例化
*
* @author zrh
*
*/
public class Demo3 {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception{
Class clz = Student.class;
// 通过反射的方式调用无参构造器来实例对象
// Student stu = (Student) clz.newInstance();
// 通过反射的方式调用带有一个参数的构造器来实例对象
// Constructor c = clz.getConstructor(String.class);
// Student stu = (Student) c.newInstance("s001");
// 通过反射的方式调用带有2个参数的构造器来实例对象
// Constructor c = clz.getConstructor(String.class,String.class);
// Student stu = (Student) c.newInstance("s001","zs");
// 通过反射的方式调用私有的的构造器来实例对象
// getConstructor与getDeclaredConstructor的区别
// getConstructor获取到的是public修饰的
// getDeclaredConstructor获取到的是所有的构造器
Constructor c = clz.getDeclaredConstructor(Integer.class);
Student stu = (Student) c.newInstance("s001");
// Student stu = new Student();
}
3.2 动态调用方法
Method m;
m.invoke
代码如下:
/**
* ~~~~~~~~~~~~~~~~~~~~~动态方法调用~~~~~~~~~~~~~~~~~~~~~~····
* @author zrh
*
*/
public class Demo4 {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception{
Class clz = Student.class;
// Method m = clz.getDeclaredMethod("hello");
// 调用的是无参的
// 第一个参数指的是,类累的类实例的类实例
// 第二个参数,指的是调用方法所携带的可变参数
// Method类invoke方法的返回值就是被调用的方法返回值
// 如果被调用的方法不具备返回值,那么返回null
// Object invoke = m.invoke(clz.newInstance());
// System.out.println(m.invoke(clz.newInstance()));
// 调用的是有参的
// Method m = clz.getDeclaredMethod("hello",String.class);
// m.invoke(clz.newInstance(), "xxx");
Method m = clz.getDeclaredMethod("add",Integer.class,Integer.class);
m.setAccessible(true);
Object invoke = m.invoke(clz.newInstance(), 20,5);
System.out.println(invoke);
}
}
3.3 读写属性
Field set/get
/**
* 反射读写属性
* @author zrh
*
*/
public class Demo5 {
public static void main(String[] args) throws Exception{
// 获取属性值
Student stu = new Student("s001","zs");
// stu.age = 23;
//
Class clz = stu.getClass();
// Field[] fields = clz.getDeclaredFields();
// for (Field field : fields) {
// field.setAccessible(true);
// System.out.println(field.getName()+":"+field.get(stu));
// }
// 设置属性值 公有的
// Field field = clz.getDeclaredField("age");
// field.set(stu, 45);
// System.out.println(stu.age);
// 设置属性值 私有的
Field field = clz.getDeclaredField("sname");
field.setAccessible(true);
field.set(stu, "lla");
System.out.println(stu.getSname());
}
}
4. 访问修饰符 getModifiers()
Java针对类、成员变量、方法,有很多修饰符,例如public、private、static、final、synchronized、abstract等,这些修饰符用来控制访问权限或其他特性。
package com.zking.refle;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Demo6 {
public static void main(String[] args) {
Class clazz = Demo6.class;
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields)
{
System.out.print(field.getName() +"->");
System.out.println(Modifier.toString(field.getModifiers()));
}
}
public int d;
public static int e;
public static final int f = 0;
private int g;
}
在这里,需要用到java.lang.reflect.Modifier这个类。Modifier提供了很多静态方法。如public static String toString(int mod)就可以输出该整数对应的所有的修饰符。public static boolean isPublic(int mod)就可以判断该整数对应的是不是包含public修饰符。
输出结果为: