概念:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
一、获取Class对象的三种方式
//1,Class.forName
Class<?> aClass = Class.forName("反射.ONE_1");
//2,.class属性
Class<ONE_1> aClass1 = ONE_1.class;
//3,对象.getClass() 方法
ONE_1 one_1 = new ONE_1();
Class<? extends ONE_1> aClass2 = one_1.getClass();
final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//classLoader的方式
final Class<?> aClass3 = systemClassLoader.loadClass("反射.ONE_1");
二、反射创建对象执行方法示例
/**
* 反射创建对象执行方法的方式
*/
ONE_1 test=(ONE_1)aClass1.newInstance();
test.test2();
/**
* 反射执行方法不带参数的方式
*/
Method test1 = aClass1.getMethod("test2");
test1.invoke(test);
/**
* 反射执行方法带参数的执行方式
*/
final Method test3 = aClass1.getMethod("test3", String.class);
test3.invoke(test,"dada");
三、反射给对象的属性赋值
/**
* 反射方式给变量赋值
*/
ONE_1 test4=(ONE_1)aClass1.newInstance();
final Field[] declaredFields1 = aClass1.getDeclaredFields();
Stream.of(declaredFields1).forEach(x->{
try {
System.out.println("赋值之前------"+x.getName()+"----------"+x.get(test4));
x.set(test4,1);
System.out.println("赋值之后------"+x.getName()+"----------"+x.get(test4));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
四、反射获取所有方法、变量、注解
/**
* 反射获取所有方法
*/
final Method[] declaredMethods = aClass1.getDeclaredMethods();
Stream.of(declaredMethods).forEach(x-> System.out.println(x.getName()));
/**
* 反射获取所有变量
*/
final Field[] declaredFields = aClass1.getDeclaredFields();
Stream.of(declaredFields).forEach(x-> System.out.println(x.getName()));
/**
* 反射获取当前所有注解
*/
final Annotation[] declaredAnnotations = aClass1.getDeclaredAnnotations();
Stream.of(declaredAnnotations).forEach(x->
System.out.println(x.annotationType().getName()));
五、反射私有方法调用、私有属性赋值
//私有属性赋值
final Field feild3 = aClass1.getDeclaredField("feild3");
System.out.println("赋值之前------"+feild3.getName()+"----------"+feild3.get(test4));
feild3.setAccessible(true);
feild3.set(test4,1);
System.out.println("赋值之后------"+feild3.getName()+"----------"+feild3.get(test4));
//私有方法调用
final Method test5 = aClass1.getDeclaredMethod("test4");
test5.setAccessible(false);
test5.invoke(test);