很多优秀的开源框架基本原理就是反射,我认为自己不能不重视它 2020.04.18
一、简单了解Java.lang.reflect包
反射机制的相关类
Class类:代表类的实体,在运行的Java应用程序中表示类和接口
Field类:代表类的成员变量(成员变量也称为类的属性)
Method类:代表类的方法
Constructor类:代表类的构造方法
首先做了一个演示类,方便你下面测试
package bao.reflectDemo;
public class ReflectDemo {
public String demoString = "希望";
public int demoInt = 1314;
private double demoDouble = 1314.00;
public ReflectDemo(String demoString ,int demoInt,double demoDouble) {
this.demoString = demoString;
this.demoInt = demoInt;
this.demoDouble = demoDouble;
}
private ReflectDemo(double demoDouble) {
this.demoDouble = demoDouble;
}
public ReflectDemo() {
}
private void printDemoDouble(double demoDouble) {
this.demoDouble = this.demoDouble + demoDouble;
System.out.println(this.demoDouble);
}
}
二、基本反射技术
我给分为三种,详情请看代码注解
package bao.reflectTest;
import org.junit.jupiter.api.Test;
public class ReflectTest {
@Test
public void test() {
//1、根据字符串来创建一个类,由于字符串可能存在问题,所以要加捕获异常
try {
Class<?> testClass1 = Class.forName(new String("java.lang.String"));
System.out.println(testClass1.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//2、根据基本类型.TYPE
Class<Boolean> testClass2 = Boolean.TYPE;
System.out.println(testClass2.getName());
//3、根据已创建的对象.getClass
ReflectTest reflectTest = new ReflectTest();
Class<? extends ReflectTest> testClass3 = reflectTest.getClass();
System.out.println(testClass3.getName());
}
@Test
public void test2() {
}
}
运行结果:
三、获取类的成员
正常情况下,我们无法使用其他类的私有方法和变量,但是反射却能帮我做到使用私有方法和变量。
这里开始我就开始引用零里写的类啦
1、我们用getDeclaredConstructors()方法,把类里的构造方法返回给一个Constructors()数组
2、getModifiers()返回了当前构造方法修饰符的特定的字节码,再通过Modifier.toString()来转换成人能读懂的字符串,哈哈
3、getParameterTypes()返回的是参数类型的数组,用Class数组接收
4、getName()获取Class的全类名
@Test
public void test2() {
//获取类的构造方法列表
ReflectDemo reflectTest = new ReflectDemo();
Class<?> testClass1 = reflectTest.getClass();
Constructor<?>[] constructors = testClass1.getDeclaredConstructors();
//获取类的构造方法的参数
for(int i = 0; i<constructors.length;i++) {
System.out.println(Modifier.toString(constructors[i].getModifiers())+":");
Class<?>[] para = constructors[i].getParameterTypes();
for(int j = 0; j<para.length;j++) {
System.out.print(para[j].getName()+" ; ");
}
System.out.println();
}
}
运行结果:
这样我们就得到了类中所有构造方法和构造方法中的参数,那么我们如何获取特定的构造方法呢?
@Test
public void test3() {
// 获取类的特定构造方法
ReflectDemo reflectTest = new ReflectDemo();
Class<?> testClass1 = reflectTest.getClass();
Constructor<?> constructor = null;
try {
constructor = testClass1.getDeclaredConstructor(String.class,int.class);
} catch (NoSuchMethodException | SecurityException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
// 获取类的构造方法的参数
System.out.println(Modifier.toString(constructor.getModifiers()) + ":");
Class<?>[] para = constructor.getParameterTypes();
for (int j = 0; j < para.length; j++) {
System.out.print(para[j].getName() + " ; ");
}
}
运行结果:
我们现在要开始调用构造函数啦
@Test
public void test4() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> testClass1 = ReflectDemo.class;
Constructor<?> constructor = testClass1.getDeclaredConstructor(double.class);
constructor.setAccessible(true);
constructor.newInstance(520.1314);
}
运行时变量的变化:
调用私有的方法
@Test
public void test5() throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class<?> testClass1 = ReflectDemo.class;
Object test = testClass1.newInstance();
Method method = testClass1.getDeclaredMethod("printDemoDouble", double.class);
method.setAccessible(true);
method.invoke(test, 480.1314);
}
运行结果:
获取类的私有字段并修改值
@Test
public void test6() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
Class<?> testClass1 = ReflectDemo.class;
Object test = testClass1.newInstance();
Field field = testClass1.getDeclaredField("demoDouble");
field.setAccessible(true);
field.set(test,1.0);
System.out.println(field.get(test).toString());
}
这篇文章的意义仅仅是熟悉一下基础语法入门,抛砖引玉,未来还要不断思考
参考链接
转载:https://blog.csdn.net/loveloose/article/details/105593538
查看评论