反射
1:反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
2:学习反射需要有以下步骤
A:首先学习字节码文件
B:第二学习 获取字节码文件的构造方法 并创建对象
C:有了对象了,就要学会获取对象中的成员变量
D:能获取对象中的成员变量了,那么还要学习成员方法
1)字节码文件的三种获取方式
①:Object类的getClass()方法:对象.getClass()
Personp = new Person();
Classc = p.getClass();
注意所有同一个类的字节码文件对象(实例)都是同一个(因为一个类就有唯一的字节码文件)
比如: Person p = new Person();
Classc = p.getClass();
Personp2 = new Person();
Classc2 = p2.getClass();
System.out.println(p== p2);// false
System.out.println(c== c2);// true
②:数据类型的静态的class属性:类名.class
Classc3 = Person.class;
③:通过Class类的静态方法forName(String className)(一般只用最后一种,前面两种了解即可)
Classc4 = Class.forName("cn.itcast_01.Person");
2)反射获取类的构造方法
public Constructor<?>[] getConstructors():所有公共构造方法
public Constructor<?>[]getDeclaredConstructors():所有构造方法 包括私有
public Constructor<T>getConstructor(Class<?>... parameterTypes):获取单个构造方法
比如:
Classclazz = Class.forName("com.heima.bean.Person");
Constructor c =clazz.getConstructor(String.class,int.class); //获取有参构造
Person p = (Person) c.newInstance("张三",23); //通过有参构造创建对象
System.out.println(p);
3)反射获取类的成员变量
Field[] fields = c.getFields();// 获取所有公共的成员变量
Field[] fields = c.getDeclaredFields();// 获取所有的成员变量
Field field = c.getField("age");// 获取单个的成员变量
比如:
Classclazz = Class.forName("com.heima.bean.Person");
Constructor c =clazz.getConstructor(String.class,int.class); //获取有参构造
Person p = (Person) c.newInstance("张三",23); //通过有参构造创建对象 //修改姓名的值
Field f =clazz.getDeclaredField("name"); //暴力反射获取字段
f.setAccessible(true); //去除私有权限
f.set(p, "李四");
System.out.println(p);
4)反射获取类的成员方法
Method[] methods = c.getMethods();// 所有公共方法,包括父类的
Method[] methods = c.getDeclaredMethods();// 本类的所有方法
Classclazz = Class.forName("com.heima.bean.Person");
Constructor c =clazz.getConstructor(String.class,int.class); //获取有参构造
Person p = (Person) c.newInstance("张三",23); //通过有参构造创建对象
Method m =clazz.getMethod("eat"); //获取eat方法
m.invoke(p);
Method m2 =clazz.getMethod("eat",int.class); //获取有参的eat方法
m2.invoke(p,10);
3:案例:动态创建某个配置文件中提供的一个类的名字的这个类的对象,并执行其方法
publicclass DemoClass {
publicvoid run() {
System.out.println("welcometo heima!");
}
}
BufferedReader br = newBufferedReader(newFileReader("xxx.properties")); //创建输入流关联xxx.properties
Class clazz =Class.forName(br.readLine()); //读取配置文件中类名,获取字节码对象
DemoClass dc = (DemoClass)clazz.newInstance(); //通过字节码对象创建对象
dc.run();
4:泛型只是在编译期间
等编译通过生成了字节码文件后,泛型就会被擦除,运行期间就没有泛型了
ArrayList<Integer>list = new ArrayList<>();
list.add(111);
list.add(222);
Class clazz =Class.forName("java.util.ArrayList"); //获取字节码对象
Method m =clazz.getMethod("add",Object.class); //获取add方法
m.invoke(list,"abc");
System.out.println(list);
5: public void setProperty(Object obj, StringpropertyName, Object value){},
此方法可将obj对象中名为propertyName的属性的值设置为value。
publicclass Tool {
//此方法可将obj对象中名为propertyName的属性的值设置为value。
publicvoid setProperty(Object obj, String propertyName, Object value) throwsException {
Class clazz =obj.getClass(); //获取字节码对象
Field f =clazz.getDeclaredField(propertyName); //暴力反射获取字段
f.setAccessible(true); //去除权限
f.set(obj,value);
}
}
publicstatic void main(String[] args) throws Exception {
Student s = new Student("张三", 23);
System.out.println(s);
Toolt = new Tool();
t.setProperty(s, "name","李四");
System.out.println(s);
}
动态代理
publicinterface Student {
publicvoid login();
publicvoid submit();
}
publicclass StudentImp implements Student {
@Override
publicvoid login() {
System.out.println("登录");
}
@Override
publicvoid submit() {
System.out.println("提交");
}
}
publicclass MyInvocationHandler implements InvocationHandler {
privateObject target;
publicMyInvocationHandler(Object target) {
this.target= target;
}
@Override
publicObject invoke(Object proxy, Method method, Object[] args)
throwsThrowable {
System.out.println("权限校验");
method.invoke(target,args); //执行被代理target对象的方法
System.out.println("日志记录");
returnnull;
}
}
StudentImpsi = new StudentImp();
si.login();
si.submit();
System.out.println("-------------------------------");
MyInvocationHandlerm = new MyInvocationHandler(si);
Students = (Student)Proxy.newProxyInstance(si.getClass().getClassLoader(),si.getClass().getInterfaces(), m);
s.login();
s.submit();
1万+

被折叠的 条评论
为什么被折叠?



