栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java 反射

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java 反射

反射
    • 一、Class类
    • 二、利用反射分析类的能力(检查类的结构)
      • 2.1 Field类
      • 2.2 Method类
      • 2.3 Constructor类
      • 2.4 Modifier类
      • 2.5 Class类
    • 三、使用反射在运行时分析对象

概念:能够分析类能力的程序称为反射(reflective)。反射机制可以用来:

  • 在运行时分析类的能力
  • 在运行时检查对象。例如编写一个适用于所有类的toString方法
  • 实现泛型数组操作代码
  • 利用method对象
一、Class类

在程序运行期间,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 Constructor 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;
    }
    
    
}
2.4 Modifier类

以上三个类都有一个名为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的访问控制。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/697272.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号