JAVA基础(12)——反射
来源:互联网 发布:白蜡杆 淘宝 编辑:程序博客网 时间:2024/05/22 06:27
JAVA基础系列规划:
- JAVA基础(1)——基本概念
- JAVA基础(2)——数据类型
- JAVA基础(3)——容器(1)——常用容器分类
- JAVA基础(4)——容器(2)——普通容器
- JAVA基础(5)——并发(1)——总体认识
- JAVA基础(6)——并发(2)——原子
- JAVA基础(7)——并发(3)——锁机制
- JAVA基础(8)——并发(4)——线程池
- JAVA基础(9)——容器(3)——并发容器
- JAVA基础(10)——IO、NIO
- JAVA基础(11)——泛型
- JAVA基础(12)——反射
- JAVA基础(13)——序列化
- JAVA基础(14)——网络编程
个人把java反射理解为一种框架,在框架内可以通过名称来控制类结构及其对象。而框架的基础就是java.lang.Class类和java.lang.reflect包中的Field、Constructor、Method、Array类。
Class类的实例表示正在运行的Java应用程序中的类和接口,保存它们的运行时类型标识信息。因此,它是java反射的开始,只有获得Class类的对象,才能通过这个对象获取其他相关信息。
获取一个类对象的Class,有三种方式:
Class classInstance = Person.class; //类型名.class获取该类型对应的Class对象Class classInstance = Class.forName("Person"); //Class类的forName()静态方法获得与字符串对应的Class对象Class classInstance = new Person().getClass(); //调用Object类对象的getClass()方法类得到Class对象
1. 获取数据结构
从Class开始,可以获取classInstance所关联的类的类名:
classInstance.getName(); //获得类的完整名字
不仅如此,类里面的所有东西都可以获取,Field、Constructor、Method,分别对应着类的成员变量、构造方法和成员方法。
Field[] fields = classInstance.getFields(); //获得类的public类型的属性
这样就获取了类的属性,但注意,只是public类型的属性,要获取类的所有属性,需要
Field[] fields = classInstance.getDeclaredFields(); //获得类的所有属性
要通过属性名称来获取类属性,就需要下面的方法了:
Field field = classInstance.getField("profession"); //public类型属性适用Field field = classInstance.getDeclaredFields("profession"); //所有类型属性均适用
获取构造方法类似:
Constructor[] cs = classInstance.getConstructors(); //获得类的public类型的构造方法Constructor[] cs2 = classInstance.getDeclaredConstructors(); //获得类的所有构造方法Class parameterTypes[] = { java.lang.String.class }; //parameterTypes参数指定构造方法的参数类型Constructor c = classInstance.getConstructor(parameterTypes); //public类型构造方法适用Constructor c2 = classInstance.getDeclaredConstructor(parameterTypes);//所有类型构造方法适用Constructor c3 = classInstance.getEnclosingConstructor(); //获取本地或匿名类Constructor对象
获取成员方法类似:
Method[] ms = classInstance.getMethods();//获得类的public类型的方法Method[] ms2 = classInstance.getDeclaredMethods();//获得类的所有方法String methodName = "setName";Class methodParaTypes[] = { java.lang.String.class }; //methodParaTypes参数指定方法的参数类型Method m2 = classInstance.getMethod(methodName, methodParaTypes);//public类型构造方法适用Method m3 = classInstance.getDeclaredMethod(methodName, methodParaTypes);//所有类型构造方法适用
2. 实例化对象
不仅可以获取类的内部结构,还可以实例化出对象,方法为:
Person p = (Person)classInstance.getConstructor(new Class[] {}).newInstance(new Object[] {}); //通过类的不带参数的构造方法创建类对象
上句是通过类的不带参数的构造方法创建类对象,还可以用另一种表达:
Person p2 = (Person)classInstance.newInstance(); //通过类的不带参数的构造方法创建类对象
对于带参数的构造方法,就只有一条路了:
Person p3 = (Person)classInstance.getConstructor(new Class[] {java.lang.String.class}).newInstance(new String[] {"best"}); //通过类的带参数的构造方法创建类对象。
3. 调用实例化对象方法
使用Method,传递参数,隐式调用执行对象的方法:
String methodName2 = "getName";Method m4 = classInstance.getMethod(methodName2);Object value = m4.invoke(new Person(), new Object[] {});
4. 举个栗子
仿commons-beanutils中复制对象,这是一个运行时复制对象的过程。
import java.lang.reflect.Field;import java.lang.reflect.Method;public class BeanHelper { public static Object copy(Object object) throws Exception { Class classInfo = object.getClass(); Object objectCopy = classInfo.newInstance(); Field fields[] = classInfo.getDeclaredFields(); for(int i=0; i<fields.length; i++) { Field field = fields[i]; String fieldName = field.getName(); String firstLetter = fieldName.substring(0, 1).toUpperCase(); String getMethodName = "get" + firstLetter + fieldName.substring(1); String setMethodName = "set" + firstLetter + fieldName.substring(1); Method getMethod = classInfo.getMethod(getMethodName, new Class[] {}); Method setMethod = classInfo.getMethod(setMethodName, new Class[] { field.getType() }); Object value = getMethod.invoke(object, new Object[] {}); setMethod.invoke(objectCopy, new Object[] { value }); } return objectCopy; }}
小测一下:
public class Main { public static void main(String[] args) throws Exception { Person p = new Person(); Person p2 = (Person)BeanHelper.copy(p); System.out.println(p2.getName()); }}
5. 反射与动态代理
在企业应用高级框架中大量用到代理模式,其原理主要就是应用到反射。
详见代理http://www.blogjava.net/baoyaer/articles/84080.html
6. 附
public class Person { private String name; private String sex; private String age; public Person() { name = "default"; sex = "male"; age = "25"; } public Person(String name) { this.name = name; sex = "male"; age = "25"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public void walk(float length) { System.out.println("walk " + length); }}
7. 参考文档
Java反射机制深入研究 JAVA的内省(introspector)与反射(reflection)
- JAVA基础(12)——反射
- Java基础—反射
- Java基础12——反射
- Java基础——反射(待续)
- Java基础(十一)——反射
- Java基础之—反射(非常重要)
- java基础——反射
- java基础——反射
- java基础——反射
- java基础——反射
- Java基础——反射
- Java基础——反射
- java基础——反射
- java反射——基础
- java基础——反射
- Java基础——反射
- Java——反射基础
- Java基础—反射机制
- spring整合redis详解
- Windows下Git Bash中文乱码
- 自定义ViewGroup实现随机泡泡效果
- find命令之xargs
- Android studio中预览布局错误:Missing styles. Is the correct theme chosen for this layou
- JAVA基础(12)——反射
- Hibernate——初步认识
- Android按home键之后,再次点击程序图标避免再次重启程序
- 概率论1
- spark 2.0 遇到java.net.URISyntaxException: Relative path in absolute URI
- pandas 常用操作
- JAVA开发13--批量将数据insert插入oracle表
- ls -al
- iOS开发之高仿斗鱼tv初探