- 一、Class类
- 二、利用反射分析类的能力(检查类的结构)
- 2.1 Field类
- 2.2 Method类
- 2.3 Constructor类
- 2.4 Modifier类
- 2.5 Class类
- 三、使用反射在运行时分析对象
概念:能够分析类能力的程序称为反射(reflective)。反射机制可以用来:
- 在运行时分析类的能力
- 在运行时检查对象。例如编写一个适用于所有类的toString方法
- 实现泛型数组操作代码
- 利用method对象
在程序运行期间,Java运行时系统始终为所有对象维护一个运行时类型标识,这个信息会跟踪每个对象所属的类。
可以使用一个特殊的Java类访问这些信息,保存这些信息的类名为Class。
获取类名对应的Class对象三种方式:
(1)通过具体对象的getClass()方法
Employee e; Class cl = e.getClass();
(2)使用Class类的静态方法forName()
String className = "java.util.Random"; Class cl = Class.forName(className); //会抛出异常
(3)使用具体类.class
Class c1 = Random.class;二、利用反射分析类的能力(检查类的结构)
在java.lang.reflect包中有三个类Field、Method、Constructor分别用于描述类的字段、方法、构造器。
2.1 Field类//列出部分
public final class Field extends AccessibleObject implements Member {
private Class> clazz; //这个field对象对应的Field类的Class
private int slot; //?
// This is guaranteed to be interned by the VM in the 1.4
// reflection implementation
private String name; //属性名
private Class> type; //属性类型,Class对象
private int modifiers; //修饰符
// Generics and annotations support
private transient String signature; //?
// generic info repository; lazily initialized
private transient FieldRepository genericInfo; //?
private byte[] annotations; //属性上的注解
// Cached field accessor created without override
private FieldAccessor fieldAccessor; //未覆盖创建的缓存字段访问器
// Cached field accessor created with override
private FieldAccessor overrideFieldAccessor; //覆盖创建的缓存字段访问器
// For sharing of FieldAccessors. This branching structure is
// currently only two levels deep (i.e., one root Field and
// potentially many Field objects pointing to it.)
//
// If this branching structure would ever contain cycles, deadlocks can
// occur in annotation code.
private Field root;
//属性名
public String getName() {
return name;
}
//属性类型
public Class> getType() {
return type;
}
//覆盖Java的访问控制,后面会看到
@Override
@CallerSensitive
public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
setAccessible0(flag);
}
boolean setAccessible0(boolean flag) {
this.override = flag;
return flag;
}
}
2.2 Method类
//列出部分
public final class Method extends Executable {
private Class> clazz; //这个method对象对应的Method类的Class
private int slot; //还不懂
// This is guaranteed to be interned by the VM in the 1.4
// reflection implementation
private String name; //方法名
private Class> returnType; //返回值类型,是Class对象
private Class>[] parameterTypes; //参数类型,Class数组
private Class>[] exceptionTypes; //异常类型,Class数组
private int modifiers; //修饰符,如public
// Generics and annotations support
private transient String signature; //签名?
// generic info repository; lazily initialized
private transient MethodRepository genericInfo; //?
private byte[] annotations; //方法上的注解,字节型数组?
private byte[] parameterAnnotations; //参数前的注解
private byte[] annotationDefault; //默认注解
private volatile MethodAccessor methodAccessor;
private Method root;
//返回方法名
@Override
public String getName() {
return name;
}
//返回值类型
public Class> getReturnType() {
return returnType;
}
//修饰符
@Override
public int getModifiers() {
return modifiers;
}
//调用包装在当前Method对象中的方法
public Object invoke(Object obj, Object... args)
//覆盖Java的访问控制,后面会看到
@Override
@CallerSensitive
public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
if (flag) checkCanSetAccessible(Reflection.getCallerClass());
setAccessible0(flag);
}
boolean setAccessible0(boolean flag) {
this.override = flag;
return flag;
}
}
2.3 Constructor类
public final class Constructor2.4 Modifier类extends Executable { private Class clazz; //这个contructor对象对应的Method类的Class private int slot; private Class>[] parameterTypes; //参数类型,class数组 private Class>[] exceptionTypes; //异常类型,class数组 private int modifiers; //修饰符 // Generics and annotations support private transient String signature; // generic info repository; lazily initialized private transient ConstructorRepository genericInfo; private byte[] annotations; //注解 private byte[] parameterAnnotations; //参数注解 //因为构造函数名就是类名,所以通过class获取对应的Class名 @Override public String getName() { return getDeclaringClass().getName(); } @Override public Class getDeclaringClass() { return clazz; } //修饰符 @Override public int getModifiers() { return modifiers; } //调用构造器 public T newInstance(Object ... initargs) //覆盖Java的访问控制,后面会看到 @Override @CallerSensitive public void setAccessible(boolean flag) { AccessibleObject.checkPermission(); if (flag) { checkCanSetAccessible(Reflection.getCallerClass()); } setAccessible0(flag); } boolean setAccessible0(boolean flag) { this.override = flag; return flag; } }
以上三个类都有一个名为getModifiers的方法,它将返回一个整数,用不同的0/1位描述所使用的修饰符,如public和static。而java.lang.reflect包中的Modifiers类的静态方法可以分析getModifiers返回的这个整数。
public class Modifier {
//修饰符对应的值,这里只列出了部分
public static final int PUBLIC = 0x00000001;
public static final int PRIVATE = 0x00000002;
public static final int PROTECTED = 0x00000004;
public static final int STATIC = 0x00000008;
public static final int FINAL = 0x00000010;
public static boolean isPublic(int mod) {
return (mod & PUBLIC) != 0;
}
public static boolean isPrivate(int mod) {
return (mod & PRIVATE) != 0;
}
public static boolean isProtected(int mod) {
return (mod & PROTECTED) != 0;
}
public static boolean isStatic(int mod) {
return (mod & STATIC) != 0;
}
public static boolean isFinal(int mod) {
return (mod & FINAL) != 0;
}
}
2.5 Class类
(1)Class类中的getFields、getMethods和getConstructors方法将分别返回这个类支持的公共字段、方法和构造器的数组,其中包括超类的公共成员。
(2)getDeclareFields、getDeclareMethods和getDeclareConstructors方法将分别返回类中声明的全部字段、方法和构造器的数组,其中包括私有成员,但不包括超类的成员。
public final class Class三、使用反射在运行时分析对象implements java.io.Serializable, GenericDeclaration,Type,AnnotatedElement { //通过String获取class对象 @CallerSensitive public static Class> forName(String className) throws ClassNotFoundException //获取Class名(全限定类名) public String getName() //获取类名(简单) public String getSimpleName() //获取公有属性、方法、构造器 @CallerSensitive public Field[] getFields() throws SecurityException @CallerSensitive public Method[] getMethods() throws SecurityException @CallerSensitive public Constructor>[] getConstructors() throws SecurityException //获取全部属性、方法、构造器 @CallerSensitive public Field[] getDeclaredFields() throws SecurityException @CallerSensitive public Method[] getDeclaredMethods() throws SecurityException @CallerSensitive public Constructor>[] getDeclaredConstructors() throws SecurityException //这个公司经常用到,如Person.class.isAssignableFrom(employee.getClass()) //判断Person是否employee的父类(或者说能否从employee转换成Person) //有点类似instance of //好像记得一个区别是isAssignableFrom是从类的角度去判断,instance of是从对象的角度 @HotSpotIntrinsicCandidate public native boolean isAssignableFrom(Class> cls); }
反射机制的默认行为受限于Java的访问控制。不过,可以调用Field、Method或Contructor对象的setAccessible方法覆盖Java的访问控制。



