java之反射
来源:互联网 发布:男人射精前的样子知乎 编辑:程序博客网 时间:2024/05/23 01:12
反射
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();
- JAVA 之"反射"
- Java 之反射机制
- Java高新技术之反射
- java 高新技术之反射
- Java反射之初识
- java高新技术之反射
- java基础之 反射
- java基础之反射
- Java之反射
- Java高新技术之反射
- 致java之反射
- java之反射
- java之反射机制
- JAVA基础之反射
- Java高级之反射
- Java之反射篇
- java之反射
- java之反射-注解
- forward和redirect引出的路径问题
- c语言:二叉排序树的实现
- 如何提取损坏压缩包中的文件
- wamp安装常见问题
- bzoj1415【NOI2005】聪聪和可可
- java之反射
- 【New AKOJ】1200: 487-3279
- Linux下使用Vim进行C/C++ 编程基础知识详解
- 4. 简单的webservices 例子
- bzoj2318 Spoj4060 game with probability Problem
- Eclipse 4.5.2 部署web应用到tomcat 8.0.33的时候出现 404错误的解决办法
- Huffman树的构造及编码
- C语言:平衡二叉树的实现(AVL)
- UML类图中几种关系的总结,EA图中会用到