一、概述:
简要的来说,Java中的反射机制就是允许程序在运行期间通过Reflection的Api来取得任何类的内部信息,并且能够直接操作任意对象的内部属性和方法。
二、Class类:
1.反射从Class类开始
要想使用反射,首先我们需要得到Class对象,然后才能通过Class对象获取Constructor、Field、Method等对象。
2.得到Class对象
- 通过对象获取Class对象:obj.getClass();
- 通过类名点上class:假设有一个Person类,Person.class这个样子
- 通过类的全限定类名来获取Class对象:Class.forName("com.buwei.Person")
- 注:一个.class对象,在方法区中只对应一个Class对象
3.加载类
我们都知道main方法是程序的入口,name是不是所有的class文件都会在main方法执行之前就已经加载到方法区中了呢,答案是不是的。一般情况下只有需要执行到某个类的代码时,才回去ClassPath中加载class文件。如果程序从头到尾都没有使用到某个类,那么这个类对应的class文件就不会被加载到内存。
可能导致一个类被加载的可能有:
- 使用一个类的静态方法
- 使用一个类的静态属性
- 创建这个类的对象
- 使用Class.forName()方法加载类
- 反序列化一个类的对象
- 加载一个类的子类时,也会加载其父类
- 加载一个类时,也会加载与该类相关的类
- 注:如果当前类没有被加载过,才会去加载,如果已经加载到方法区中了,就不可能再去加载。
4.Class类的方法
方法1:
- String getName():返回类名;
- String getSimpleName():返回简单类名,不包含包名,但数组类型使用它比价方便;
- Class getSuperClass():获取父类,Object.class.getSuperClass()返回null;
- int getModifiers():获取类的所有修饰符信息;
方法2:
- Constructor getConstructor(Class... parameterTypes):通过指定的参数类型获取共有的构造器反射对象;
- Constructor[] getConstructors():获取所有的共有构造器;
- Constructor getDeclaredConstructor(Class ... paremeterTypes):通过指定参数类型获取构造器反射对象,包含私有构造器对象
- Constructor[] getDeclaredConstructors():获取所有构造器对象。包含私有构造器;
- Field getField(String name):通过名字获取共有属性反射对象,包含父类中声明的共有属性;
- Field[] getFields():获取所有公有属性反射对象,包含父类中声明的公有属性;
- Field getDeclaredField(String name):通过名字获取本类中的某个属性,包含本类的private属性,但是不包含父类中声明的任何属性;
- Field[] getDeclaredFields():获取本类中声明的所有属性,包含private属性,但不包含父类中声明的任何属性;
- Method getMethod(String name,Class ... parameterTypes):通过方法名和方法参数类型获取方法反射对象
- Method[] getMethods():获取所有公有方法,包含父类中的公有方法,但不包含任何私有方法;
- Method getDeclaredMethod(String name, Class… parameterTypes):通过方法名和方法参数类型获取本类中声明的方法的反射对象,包含本类中的私有方法,但不包含父类中的任何方法;
- Method[] getDeclaredMethods():获取本类中所有方法,包含本类中的私有方法,但不包含父类中的任何方法。
方法3:
- boolean isArray():是否为数组类型;
- boolean isAnnotation():是否为注解类型;
- boolean isAnnotationPresent(Class annotationClass):当前类是否被annotationClass注解了;
- boolean isEnum:是否为枚举类型;
- boolean isInterface:是否为接口类型;
- boolean isPrimitive:是否为基本类型;
- boolean isSynthetic:是否为引用类型;
方法4:
- T newInstance:使用本类的无参构造器来创建本类的对象;
三、其他反射类
其他反射类偶在Java.lang.reflect包下
1.AccessibleObject
AccessibleObject类是Constructor、method、Field三个类的父类
- Annotation getAnnotation(Class annotationClass):获取作用在当前成员上的annotationClass类型的注解对象;
- Annotation[] getAnnotations():获取作用在当前成员上的所有注解对象;
- boolean isAccessible():判断当前成员是否可访问;
- void setAccessible(boolean flag):设置当前成员是否可访问。
2.Constructor
- String getName():获取构造器名;
- int getModifiers():获取构造器上的所有修饰符信息;
- Class getDeclaringClass():获取构造器所属的类型;
- Class[] getParameterTypes():获取构造器的所有参数的类型;
- Class[] getExceptionTypes():获取构造器上声明的所有异常类型;
- T newInstance(Object… initargs):通过构造器反射对象调用构造器。
3.Method
- String getName():获取方法名;
- int getModifiers():获取方法上的所有修饰符信息;
- Class getDeclaringClass():获取方法所属的类型;
- Class[] getParameterTypes():获取方法的所有参数的类型;
- Class[] getExceptionTypes():获取方法上声明的所有异常类型;
- Class getReturnType():获取方法的返回值类型;
- Object invode(Object obj, Object… args):通过方法反射对象调用方法,如果当前方法是实例方法,那么当前对象就是obj,如果当前方法是static方法,那么可以给obj传递null。args表示是方法的参数;
4.Field
- String getName():获取属性名;
- int getModifiers():获取属性上的所有修饰符信息;
- Class getDeclaringClass():获取属性所属的类型;
- Class getType():获取当前属性的类型;
- Object get(Object obj):获取obj对象的当前属性值;
- void set(Object obj, Object value):设置obj对象的当前属性值为value;
- XXX getXXX(Object obj):如果当前属性为基本类型,可以使用getXXX()系列方法获取基本类型属性值。假如当前属性为int类型,那么可以使用getInt(Object obj)方法获取obj对象的当前属性值;
5.Modifier
modifier类有一系列的static方法用来解析其他getModifiers()方法返回的int值。
Method m = … int m = m.getModifiers(); boolean b1 = Modifier.isAbstract(m);//解析m中是否包含abstract修饰 boolean b2 = Modifier.isStatic(m);//解析m中是否包含static修饰 String s = Modifiers.toString(m);//把所有修饰都转换成字符串 |