课堂思维导图:

1.什么是反射:?
?反射java语言中的一种机制,通过这种机制可以动态的实例化对象,读写属性,调用方法。
2.类类:
获取类类的类对象的三种方式 ?* 1、Class.forName ?* 2.类.class ?* 3.类类的类对象的类实例.getClass();
?
public static void main(String[] args) throws Exception {
// student.class
Class stuClz1 = Class.forName("com.pjl.reflect.Student");
// 通用查询
Class stuClz2 =Student.class;
// 通用
Class stuClz3 =new Student().getClass();
}
3.反射实例化
3.1调用无参构造方法创建了一个学生对象
首先获取类对象
public static void main(String[] args) throws Exception {
Class stuClz1 = Class.forName("com.pjl.reflect.Student");
Student stu1= (Student) stuClz1.newInstance();
stu1.hello();
}
?
?其次调用无参构造方法对一个类进行实例化

展示效果:??

?
如果不调用无参 否则会报:

?解决方法:接一个无参构造
3.2怎么通过反射调用有参构造器?
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
Constructor<Student> c= stuClz1.getConstructor(String.class);
Student s= c.newInstance("s001");
}
?用的是student类里的有参:

效果展示:?

?
?
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
Constructor<Student> c2= stuClz1.getConstructor(String.class,String.class);
Student s2= c2.newInstance("s001","zs");
}
效果展示:
?
?
3.3比较getDeclaredConstructor和?getConstructor的区别
区别:getDeclaredConstructor:能获得私有和公有的
? ? ? ? ??getConstructor:获得公有的构造器
举例:
首先我们先用getConstructor实验
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
Constructor<Student> c3= stuClz1.getConstructor(Integer.class);
Student s3= c3.newInstance(26);
}
会报错(没有匹配的方法?)

?原因:无法获取私有的构造方法
?那么换getDeclaredConstructor试验:
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
Constructor<Student> c3= stuClz1.getDeclaredConstructor(Integer.class);
Student s3= c3.newInstance(26);
}
也会报错(没有访问权限)?

?
解决方法:????//打开权限
c3.setAccessible(true);
整体代码结合:
package com.pjl.reflect;
import java.lang.reflect.Constructor;
/**
* 反射实例化
* @author zjjt
*
*/
public class Demo2 {
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
System.out.println("=======================");
Student stu1= (Student) stuClz1.newInstance();
stu1.hello();
System.out.println("=======================");
//怎么通过反射调用有参构造器
// 区别: getDeclaredConstructor:能获得私有和公有的构造器 getConstructor:获得私有的构造器
Constructor<Student> c= stuClz1.getConstructor(String.class);
Student s= c.newInstance("s001");
System.out.println("=======================");
Constructor<Student> c2= stuClz1.getConstructor(String.class,String.class);
Student s2= c2.newInstance("s001","zs");
System.out.println("=======================");
Constructor<Student> c3= stuClz1.getDeclaredConstructor(Integer.class);
c3.setAccessible(true);
Student s3= c3.newInstance(26);
}
}
效果展示:
?
?
?4.反射方法调用
//?? ??? ?invoke ?参数1:求实例,在这里指的是Student类实例 //? ? ? ? ? ? ? ? ? ? 参数2:当前被调用的方法,传递参数值 //?? ??? ?invoke的返回值,就是被反射调用的方法的返回值,如果被调用
package com.pjl.reflect;
import java.lang.reflect.Method;
public class Demo3 {
public static void main(String[] args) throws Exception {
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
Student s=stuClz1.newInstance();
System.out.println("=======================");
Method m1= stuClz1.getDeclaredMethod("hello");
System.out.println(m1.invoke(s));
System.out.println("=======================");
Method m2= stuClz1.getDeclaredMethod("hello",String.class);
System.out.println(m2.invoke(s,"zs"));
System.out.println("=======================");
Method m3= stuClz1.getDeclaredMethod("add",Integer.class,Integer.class);
m3.setAccessible(true);
System.out.println(m3.invoke(s,10,5));
}
}
效果展示:
?
?
?5.反射读写属性
package com.pjl.reflect;
import java.lang.reflect.Field;
/**
* 反射读取属性
* @author zjjt
*
*/
public class Demo4 {
public static void main(String[] args) throws Exception {
//获取类对象
Class<Student> stuClz1 = (Class<Student>) Class.forName("com.pjl.reflect.Student");
//获取类对象的属性
Student s=stuClz1.newInstance();
System.out.println("=======================");
Field f= stuClz1.getDeclaredField("sname");
f.setAccessible(true);
//反射写属性
f.set(s,"zs");
System.out.println(s.getSname());
//反射读属性
System.out.println(f.get(s));
System.out.println("=======================");
//比较oop与反射读取属性值的方式
Student st=new Student("s002","ls");
st.age=22;
System.out.println(st.getSid());
System.out.println(st.age);
System.out.println("=======================");
//反射读取该对象所有属性值
Field[] fields= stuClz1.getDeclaredFields();
for (Field ff: fields) {
ff.setAccessible(true);
System.out.println(ff.getName()+":"+ff.get(st));
}
}
}
展示效果:

?
总结:反射是框架设计的灵魂!
|