反射:
反射应用在一些通用性比较高的代码中。
一般的框架,大多数都是使用反射来实现的。
在框架开发中,都是基于配置文件开发。
在配置文件红配置了类,可以通过反射得到类中的所有内容,可以让类中某个方法执行。
类中所有的内容:属性、没有参数的构造方法、有参数的构造方法、普通方法。
分析反射的原理:
首先把需要java文件保存到本地硬盘 .java文件
编译java文件成 .class文件
使用jvm,把class文件通过类加载加载到内存中
万事万物都是对象,class文件在内存中使用class类表示
当使用反射的时候,首先需要获取到class类,得到这个类之后,就可以得到class文件里的所有内容。
-包含属性,构造方法,普通方法
属性通过一个类 Filed
构造方法通过一个类 Construction
普通方法通过一个类 Method
使用反射操作类里面的无参数的构造方法:
首先获取到Class类
//获取Class类的三种方式
Class class1 = testDemoperson.class;
Class class2 = new testDemoperson().getClass();
Class class3 = Class.forName("test04.testDemoperson");
比如:要对一个类进行实例化,可以new,不使用new,怎么获取?
//得到Class
Class c3 = Class.forName("test04.testDemoperson");
//得到testDemoperson类实例
testDemoperson p = (testDemoperson) c3.newInstance();
使用反射操作有参数的构造方法:
publicstaticvoid test2() throws Exception{
//得到Class
Class c1 = Class.forName("test04.testDemoperson");
//使用有参数的构造方法
//c1.getConstructor();//获取所有的构造方法。
//传递有参数的构造方法里面的参数类型,类型使用class形式传递
Constructor cs = c1.getConstructor(String.class,String.class);
//通过有参数的构造方法设置值
//通过有参数的构造方法创建person实例
testDemoperson p8 = (testDemoperson) cs.newInstance("lisi","200");
System.out.println(p8.getId()+" "+p8.getName());
}
使用反射来操作属性:
publicstaticvoid test3() throws Exception {
//得到Class类
Class c9 = Class.forName("test04.testDemoperson");
//得到name属性
//得到testDemoperson的实例
testDemoperson p11 = (testDemoperson) c9.newInstance();
//通过这个方法得到属性,参数是属性的名称
Field f = c9.getDeclaredField("name");
//操作的是私有的属性,不让操作,设置可以操作私有属性setAccessible(true);
f.setAccessible(true);
//设置name值 set方法,两个参数:第一个是参数的实例,第二个是设置的值。
f.set(p11, "王5");//相当于在 p.name = "王5";
System.out.println(f.get(p11));//相当于p.name
}
使用反射操作普通方法:
使用Method类表示普通方法
publicstaticvoid test6() throws Exception{
//得到Class类
Class c5 = Class.forName("test04.testDemoperson");
//得到testDemoperson实例
testDemoperson p7 = (testDemoperson) c5.newInstance();
//得到普通的方法
//c5.getDeclaredMethods();//得到所有的普通方法
//传递两个参数:第一个参数是方法名称,第二个参数是通过方法设置的值
Method m4 = c5.getDeclaredMethod("setName", String.class);
//让setName方法执行,执行设置值
//使用invoke(p4,"张");
//传递两个参数,第一个是testDemoperson的实例,第二个参数是设置的值
//执行了invoke方法之后,相当于执行了setName方法,同时通过这个方法设置了一个值叫“张”
m4.invoke(p7, "张");
System.out.println(p7.getName());
}
注意:
操作私有的方法,需要设置值是true
m4.setAccessible(true);
当操作的方法是静态的方法的时候,因为静态方法调用方式是类名.方法名,
不需要类的实例。使用反射操作静态方法的时候也是不需要实例的。
在invokie方法的第一个参数里面,写一个null
m4.invoke(null,“张”);