java reflect包分析

在分析reflect之前,我们需要知道该包的作用:

该包用于通过类名获取类的信息,只要是类中定义的信息都可以通过反射获取到,可以获取到类定义的各个部分,如Method,Field,Constructor,Package

在了解了作用之后我们再来看看其继承体系


首先我们先来分析AnnotatedElement  Member  GenericDeclaration Type 这几个接口的作用,其中Type接口以及在上一篇博客中做了介绍

地址如下:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

首先是AnnotatedElement  接口的作用:

Java使用Annotation接口来代表程序元素前面的注解,该接口是所有Annotation类型的父接口。

除此之外,Java在java.lang.reflect 包下新增了AnnotatedElement接口,该接口代表程序中可以接受注解的程序元素。也就是除了实现该接口的类之外其余的类都无法接受注解元素。这些类有:

Class:类定义
Constructor:构造器定义
Field:累的成员变量定义
Method:类的方法定义
Package:类的包定义,

我们首先向看看其接口定义

/**
 * 作用:只有该类的子类才能使用注解元素
 */
public interface AnnotatedElement {

    /**
     * 如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。
     */
    default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
        return getAnnotation(annotationClass) != null;
    }

    /**
     * 如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null
     */
    <T extends Annotation> T getAnnotation(Class<T> annotationClass);

    /**
     * 返回此元素上存在的所有注解。(如果此元素没有注解,则返回长度为零的数组。)
     * 该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
     */
    Annotation[] getAnnotations();

    default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
        T[] result = getDeclaredAnnotationsByType(annotationClass);

        if (result.length == 0 && // Neither directly nor indirectly present
                this instanceof Class && // the element is a class
                AnnotationType.getInstance(annotationClass).isInherited()) { // Inheritable
            Class<?> superClass = ((Class<?>) this).getSuperclass();
            if (superClass != null) {
                // Determine if the annotation is associated with the
                // superclass
                result = superClass.getAnnotationsByType(annotationClass);
            }
        }

        return result;
    }


    default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
        Objects.requireNonNull(annotationClass);
        // Loop over all directly-present annotations looking for a matching one
        for (Annotation annotation : getDeclaredAnnotations()) {
            if (annotationClass.equals(annotation.annotationType())) {
                // More robust to do a dynamic cast at runtime instead
                // of compile-time only.
                return annotationClass.cast(annotation);
            }
        }
        return null;
    }

    default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {
        Objects.requireNonNull(annotationClass);
        return AnnotationSupport.
                getDirectlyAndIndirectlyPresent(Arrays.stream(getDeclaredAnnotations()).
                                collect(Collectors.toMap(Annotation::annotationType,
                                        Function.identity(),
                                        ((first, second) -> first),
                                        LinkedHashMap::new)),
                        annotationClass);
    }

    /**
     * 返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释。(
     */
    Annotation[] getDeclaredAnnotations();
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

再看Member接口

作用:Member表示一个类中的成员,包括成员变量、方法、构造方法三种实现

所有已知实现类:
Constructor(构造方法), Field(成员变量), Method(方法)

去定义如下:

/**
 * 成员是一种接口,反映有关单个成员(字段或方法)或构造方法的标识信息。
 * 在Java中,一个类别可以定义Field成员及方法(Method) 成员。
 */
public interface Member {

    /**
     * 标识类或接口的所有公共成员(包括继承成员)的集合。
     */
    public static final int PUBLIC = 0;

    /**
     * 标识类或接口的所有已声明成员的集合。不包括继承成员。
     */
    public static final int DECLARED = 1;

    /**
     * 返回表示声明由此 Member 表示的成员或构造方法的类或接口的 Class 对象
     */
    public Class<?> getDeclaringClass();

    /**
     * 返回此 Member 表示的底层成员或构造方法的简单名称
     */
    public String getName();

    /**
     * 作为整数返回由此 Member 所表示的成员或构造方法的 Java 语言修饰符。应该使用 Modifier 类解码整数中的修饰符。
     * 上句话的意思,就是Modifier类中包含了 相应的整数与修饰符的关系,具体可以看java.lang.reflect.Modifier类。
     * 修饰符包括public, protected, private, final, static, abstract 和interface及Java虚拟机的常数,
     * 他们应该使用Modifier类的方法进行解码。
     */
    public int getModifiers();

    /**
     * 如果此成员是编译器引入的,则返回 true;否则,返回 false。
     */
    public boolean isSynthetic();
}

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

再来看看GenericDeclaration 

/**
 * 声明类型变量的所有实体的公共接口。
 * 也就是说只有实现了该接口才能在对应的实体上声明(定义)类型变量(泛型)
 */
public interface GenericDeclaration extends AnnotatedElement {

    /**
     * 返回声明顺序的 TypeVariable 对象的数组,这些对象表示由此 GenericDeclaration 对象表示的一般声明声明的类型变量。
     * 如果底层的一般声明未声明任何类型变量,则返回一个 0 长度的数组。
     */
    public TypeVariable<?>[] getTypeParameters();
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

最后看完AccessibleObject类就可以正式开始反射的学习的

先来看看其定义:一下仅仅是部分方法

/**
 * 作用:它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。简单的说,就是可以违反java的权限控制体系
 *
 * 对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor
 * 对象来设置或获得字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。
 */
public class AccessibleObject implements AnnotatedElement {

    static final private java.security.Permission ACCESS_PERMISSION =
            new ReflectPermission("suppressAccessChecks");


    /**
     * 使用单一安全性检查(为了提高效率)为一对象设置 accessible 标志。
     * 如果存在安全管理器,则在 ReflectPermission("suppressAccessChecks") 权限下调用 checkPermission 方法。
     * 当flag 为 true,表示不开启安全检查,但是不能更改输入 object的任何元素的可访问性
     * (例如,如果元素对象是 Class 类的 Constructor 对象),则会引发 SecurityException。
     * 如果发生 SecurityException,对于少于(不包括)发生异常的元素的数组元素,可以将对象的可访问性设置为 flag;
     * 对于超出(包括)引发异常的元素的那些元素,则不更改其可访问性.
     */
    public static void setAccessible(AccessibleObject[] array, boolean flag)
            throws SecurityException {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
        for (int i = 0; i < array.length; i++) {
            setAccessible0(array[i], flag);
        }
    }

    /**
     * 获得此对象的 accessible 标志的值。
     * 此对象的返回值 就是accessible的标志值,一般情况下无论 public,private,protected,默认等修饰的属性的access值均为false
     * 注意他的意思并非是访问权限而是对该自己执行安全检查 (isAccessible 是否可访问的)
     */
    public boolean isAccessible() {
        return override;
    }

}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

扯了这么久终于开始进入正题了

首先需要了解的同时也是整个反射体系的基石 Class

在文章最开头的部分中,我们提到过反射就是可以获取类定义的各个部分诸如,Method ,Field,Constructor,Package,那么这部分的实例该如何获取呢?

答案就是通过Class类的API了。

在详细了解Class之前,我们先大致的了解一下Class到底是什么以及和class有什么区别。

1.所有的类文件都有共同的属性,所以可以先上抽取,把这些共性内容封装成一个类,这个类就是Class(描述字节码文件对象)。

Class类中就包含的属性有:field, method ,constructor

field:包含修饰符,类型,变量名等,因此也可以将字段封装成为一个对象,用来获取类中的field内容,这个对象描述就是Field,同样的方法和构造函数也被封装成Method与Constructor。想要对一个类进行内容的获取,必须想要获取该字节码描述对象,也就是Class对象。

2.Class类描述字节码信息,包含类名,访问属性,所属包,字段列表,方法名称列表等等,每一个字节码实例就是一个class的实例对象。

3.Class和class的区别

a.class:java中的类用来描述一类事物的共性,比如狗类,至于狗的毛是什么颜色,具体需要看实际的狗实例

b.Class:java中所有的class都是Class的子类。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

如何获取Class对象

1.通过getClass方法获取

Class klass=new Dog().getClass; //使用此方法的前提是需要得到具体的实例如例子中的 new Dog();

2.通过静态属性class获取

Class klass=Dog.class; //使用此方法的前提就是需要得到具体的类,如Dog就是一个类

3.通过Class.forName的方式获取

Class klass=Class.forName("类的全限定名") //此方式不和任何的具体类发生绑定关系,利于扩展,但是可能抛出找不到类的异常。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

java预定的义的Class

包括基本类型(byte short int long float double char boolean)

Integer.TYPE是Integer类的一个常量,它代表此包装类型包装的基本类型的字节码,所以和int.class是相等的。基本数据类型的字节码都可以用与之对应的包装类中的TYPE常量表示

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Class中包含的方法主要如下

/**
 * 对所有class共性的抽象
 * T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是 Class<String>。如果将被建模的类未知,则使用 Class<?>。
 * Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。
 * 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
 * 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象。
 * Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
 */
public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type, AnnotatedElement {

    /**
     * 私有的类加载器。需要的参数为类加载器
     */
    private Class(ClassLoader loader) {
        classLoader = loader;
    }

    /**
     * 将对象转换为字符串。
     * 字符串的表示形式为字符串 "class" 或 "interface" 后面紧跟一个空格,然后是该类的完全限定名,它具有 getName 返回的那种格式。
     * 如果此 Class 对象表示一个基本类型,则此方法返回该基本类型的名称。如果该 Class 对象表示 void,则此方法返回 "void"。
     */
    public String toString() {
        return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
                + getName();
    }

    /**
     * toGenericString是Constructor,Method,Field这三个类专有的方法,如Constructor类,
     * 给出的是对应的构造函数的细节,比如修饰符,构造函数名和参数列表等
     */
    public String toGenericString() {
       return "细节省略";
    }

    /**
     * 返回与带有给定字符串名的类或接口相关联的 Class 对象。调用此方法等效于:
     * Class.forName(className, true, currentLoader)
     */
    @CallerSensitive    //JVM专用注解  @CallSensitive用来找到真正发起反射请求的类
    public static Class<?> forName(String className) throws ClassNotFoundException {
        //细节省略  原因在于调用的最终处理方法是一个本地方法。
    }

    /**
     * 创建此 Class 对象所表示的类的一个新实例。
     * 如同用一个带有一个空参数列表的 new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。
     */
    @CallerSensitive
    public T newInstance() throws InstantiationException, IllegalAccessException {

    }

    /**
     * 判定指定的 Object 是否与此 Class 所表示的对象赋值兼容。此方法是 Java 语言 instanceof 运算符的动态等效方法。
     * 如果指定的 Object 参数非空,且能够在不引发 ClassCastException 的情况下被强制转换成该 Class 对象所表示的引用类型,
     * 则该方法返回 true;否则返回 false。
     */
    public native boolean isInstance(Object obj);

    /**
     * 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。
     * 如果是则返回 true;否则返回 false。如果该 Class 表示一个基本类型,且指定的 Class 参数正是该 Class 对象,
     * 则该方法返回 true;否则返回 false。
     */
    public native boolean isAssignableFrom(Class<?> cls);

    /**
     * 判定指定的 Class 对象是否表示一个接口类型。
     */
    public native boolean isInterface();

    /**
     * 判定此 Class 对象是否表示一个数组类。
     */
    public native boolean isArray();

    /**
     * 判定指定的 Class 对象是否表示一个基本类型。
     * Primitive:基本的,原始的
     */
    public native boolean isPrimitive();

    /**
     * 如果此 Class 对象表示一个注解类型则返回 true。
     * 注意,如果此方法返回 true,则 isInterface() 也返回 true,因为所有的注释类型同时也是接口。
     */
    public boolean isAnnotation() {
        return (getModifiers() & ANNOTATION) != 0;
    }

    /**
     * 如果此类是复合类,则返回 true,否则 false。
     */
    public boolean isSynthetic() {
        return (getModifiers() & SYNTHETIC) != 0;
    }

    /**
     * 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。
     * 如果此类对象表示的是非数组类型的引用类型,则返回该类的二进制名称
     * 如果此类对象表示一个基本类型或 void,则返回的名字是一个与该基本类型或 void 所对应的 Java 语言关键字相同的 String
     * 如果此类对象表示一个数组类,则名字的内部形式为:表示该数组嵌套深度的一个或多个 '[' 字符加元素类型名。
     */
    public String getName() {

    }

    /**
     * 返回该类的类加载器。
     * 有些实现可能使用 null 来表示引导类加载器。如果该类由引导类加载器加载,则此方法在这类实现中将返回 null。
     * 如果存在安全管理器,并且调用者的类加载器不是 null,也不同于或是请求其类加载器的类的类加载器的祖先,
     * 则此方法通过 RuntimePermission("getClassLoader") 权限调用此安全管理器的 checkPermission 方法,
     * 以确保可以访问该类的类加载器。如果此对象表示一个基本类型或 void,则返回 null。
     * @return
     */
    @CallerSensitive
    public ClassLoader getClassLoader() {

    }

    /**
     * 按声明顺序返回 TypeVariable 对象的一个数组,这些对象表示用此 GenericDeclaration 对象所表示的常规声明来声明的类型变量。
     * 如果底层常规声明不声明类型变量,则返回长度为 0 的数组。
     */
    @SuppressWarnings("unchecked")
    public TypeVariable<Class<T>>[] getTypeParameters() {
    }

    /**
     * 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
     * 如果此 Class 表示 Object 类、一个接口、一个基本类型或 void,则返回 null。
     * 如果此对象表示一个数组类,则返回表示该 Object 类的 Class 对象。
     */
    public native Class<? super T> getSuperclass();

    /**
     * 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。
     */
    public Type getGenericSuperclass() {

    }

    /**
     * 获取此类的包。此类的类加载器用于查找该包。
     * 如果该类是通过引导类加载器加载的,则搜索从 CLASSPATH 加载的包的集合,以查找该类的包。
     * 如果所有包对象都不是用该类的类加载器加载的,则返回 null。只有该类的附属清单中定义了信息,
     * 并且类加载器使用该清单中的属性创建了包实例时,包才具有版本和规范属性。
     */
    public Package getPackage() {
    }

    /**
     * 确定此对象所表示的类或接口实现的接口。
     */
    public Class<?>[] getInterfaces() {

    }

    /**
     * 返回表示某些接口的 Type,这些接口由此对象所表示的类或接口直接实现。
     */
    public Type[] getGenericInterfaces() {
    }

    /**
     * 返回表示数组组件类型的 Class。如果此类不表示数组类,则此方法返回 null。
     */
    public native Class<?> getComponentType();

    /**
     * 返回此类或接口以整数编码的 Java 语言修饰符。
     * 修饰符由 Java 虚拟机的 public、protected、private、final、static、abstract 和 interface 对应的常量组成;
     * 它们应当使用 Modifier 类的方法来解码。
     * 如果底层类是数组类,则其 public、private 和 protected 修饰符与其组件类型的修饰符相同。
     * 如果此 Class 表示一个基本类型或 void,则其 public 修饰符始终为 true,protected 和 private 修饰符始终为 false。
     * 如果此对象表示一个数组类、一个基本类型或 void,则其 final 修饰符始终为 true,其接口修饰符始终为 false。
     * 该规范没有给定其他修饰符的值。
     */
    public native int getModifiers();

    /**
     * 获取此类的标记
     */
    public native Object[] getSigners();


    /**
     * 如果此 Class 对象表示某一方法中的一个本地或匿名类,则返回 Method 对象,它表示底层类的立即封闭方法。否则返回 null。
     * 特别地,如果底层类是由一个类型声明、实例初始值设定项或静态初始值设定项立即封闭的本地或匿名类,则此方法返回 null。
     */
    @CallerSensitive
    public Method getEnclosingMethod() throws SecurityException {
    }


    /**
     * 如果该 Class 对象表示构造方法中的一个本地或匿名类,则返回 Constructor 对象,它表示底层类的立即封闭构造方法。
     * 否则返回 null。特别地,如果底层类是由一个类型声明、实例初始值设定项或静态初始值设定项立即封闭的本地或匿名类,
     * 则此方法返回 null。
     */
    @CallerSensitive
    public Constructor<?> getEnclosingConstructor() throws SecurityException {
    }

    /**
     * 如果此 Class 对象所表示的类或接口是另一个类的成员,则返回的 Class 对象表示该对象的声明类。
     * 如果该类或接口不是其他类的成员,则此方法返回 null。如果此 Class 对象表示一个数组类、基本类型或 void,则此方法返回 null。
     */
    @CallerSensitive
    public Class<?> getDeclaringClass() throws SecurityException {
    }

    /**
     * 返回底层类的立即封闭类。如果底层类是顶层类,则此方法返回 null。
     */
    @CallerSensitive
    public Class<?> getEnclosingClass() throws SecurityException {
    }

    /**
     * 返回源代码中给出的底层类的简称。如果底层类是匿名的则返回一个空字符串。
     * 数组的简称即附带 "[]" 的组件类型的简称。特别地,组件类型为匿名的数组的简称是 "[]"。
     */
    public String getSimpleName() {
    }

    /**
     * 返回类型的名称
     */
    public String getTypeName() {
    }

    /**
     * 返回 Java Language Specification 中所定义的底层类的规范化名称。
     * 如果底层类没有规范化名称(即如果底层类是一个组件类型没有规范化名称的本地类、匿名类或数组),则返回 null。
     */
    public String getCanonicalName() {
    }

    /**
     * 当且仅当底层类是匿名类时返回 true。
     */
    public boolean isAnonymousClass() {
    }

    /**
     * 当且仅当底层类是本地类时返回 true。
     */
    public boolean isLocalClass() {
    }

    /**
     * 当且仅当底层类是成员类时返回 true。
     */
    public boolean isMemberClass() {
    }

    /**
     * 返回一个包含某些 Class 对象的数组,这些对象表示属于此 Class 对象所表示的类的成员的所有公共类和接口。
     * 包括从超类继承的公共类和接口成员以及该类声明的公共类和接口成员。
     * 如果此 Class 对象没有公共成员类或接口,则此方法返回一个长度为 0 的数组。
     * 如果此 Class 对象表示一个基本类型、一个数组类或 void,则此方法也返回一个长度为 0 的数组。
     */
    @CallerSensitive
    public Class<?>[] getClasses() {
    }

    /**
     * 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
     * 返回数组中的元素没有排序,也没有任何特定的顺序。
     * 如果类或接口没有可访问的公共字段,或者表示一个数组类、一个基本类型或 void,则此方法返回长度为 0 的数组。
     * 特别地,如果该 Class 对象表示一个类,则此方法返回该类及其所有超类的公共字段。
     * 如果该 Class 对象表示一个接口,则此方法返回该接口及其所有超接口的公共字段。
     * 该方法不反映数组类的隐式长度字段。用户代码应使用 Array 类的方法来操作数组。
     */
    @CallerSensitive
    public Field[] getFields() throws SecurityException {
    }

    /**
     * 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口
     * (包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
     * 数组类返回从 Object 类继承的所有(公共)member 方法。返回数组中的元素没有排序,也没有任何特定的顺序。
     * 如果此 Class 对象表示没有公共成员方法的类或接口,或者表示一个基本类型或 void,则此方法返回长度为 0 的数组。
     * 类初始化方法 <clinit> 不包含在返回的数组中。如果类声明了带有相同参数类型的多个公共成员方法,则它们都会包含在返回的数组中。
     */
    @CallerSensitive
    public Method[] getMethods() throws SecurityException {
    }

    /**
     * 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
     * 如果该类没有公共构造方法,或者该类是一个数组类,或者该类反映一个基本类型或 void,则返回一个长度为 0 的数组。
     * 注意,此方法返回 Constructor<T> 对象的数组(即取自此类构造方法的数组)时,此方法的返回类型是 Constructor<?>[],
     * 不是 预期的 Constructor<T>[]。此少量信息的返回类型是必需的,因为从此方法返回之后,
     * 该数组可能被修改以保存不同类的 Constructor 对象,而这将违反 Constructor<T>[] 的类型保证。
     */
    @CallerSensitive
    public Constructor<?>[] getConstructors() throws SecurityException {
    }

    /**
     * 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。name 参数是一个 String,用于指定所需字段的简称。
     * 要反映的字段由下面的算法确定。设 C 为此对象所表示的类:
     * 1.如果 C 声明一个带有指定名的公共字段,则它就是要反映的字段
     * 2.如果在第 1 步中没有找到任何字段,则该算法被递归地应用于 C 的每一个直接超接口。直接超接口按其声明顺序进行搜索。
     * 3.如果在第 1、2 两步没有找到任何字段,且 C 有一个超类 S,则在 S 上递归调用该算法。如果 C 没有超类,则抛出 NoSuchFieldException。
     */
    @CallerSensitive
    public Field getField(String name) throws NoSuchFieldException, SecurityException {
    }

    /**
     * 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
     * name 参数是一个 String,用于指定所需方法的简称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组。
     * 如果 parameterTypes 为 null,则按空数组处理。
     */
    @CallerSensitive
    public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {
    }

    /**
     * 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。
     * parameterTypes 参数是 Class 对象的一个数组,这些 Class 对象按声明顺序标识构造方法的形参类型。
     * 如果此 Class 对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例。
     * 要反映的构造方法是此 Class 对象所表示的类的公共构造方法,其形参类型与 parameterTypes 所指定的参数类型相匹配。
     */
    @CallerSensitive
    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {
    }

    /**
     * 返回 Class 对象的一个数组,这些对象反映声明为此 Class 对象所表示的类的成员的所有类和接口。
     * 包括该类所声明的公共、保护、默认(包)访问及私有类和接口,但不包括继承的类和接口。
     * 如果该类不将任何类或接口声明为成员,或者此 Class 对象表示基本类型、数组类或 void,则此方法返回一个长度为 0 的数组。
     */
    @CallerSensitive
    public Class<?>[] getDeclaredClasses() throws SecurityException {
    }

    /**
     * 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
     * 包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段。返回数组中的元素没有排序,也没有任何特定的顺序。
     * 如果该类或接口不声明任何字段,或者此 Class 对象表示一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
     */
    @CallerSensitive
    public Field[] getDeclaredFields() throws SecurityException {
    }

    /**
     * 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
     * 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。返回数组中的元素没有排序,也没有任何特定的顺序。
     * 如果该类或接口不声明任何方法,或者此 Class 对象表示一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
     * 类初始化方法 <clinit> 不包含在返回数组中。如果该类声明带有相同参数类型的多个公共成员方法,则它们都包含在返回的数组中。
     */
    @CallerSensitive
    public Method[] getDeclaredMethods() throws SecurityException {
    }

    /**
     * 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
     * 它们是公共、保护、默认(包)访问和私有构造方法。返回数组中的元素没有排序,也没有任何特定的顺序。
     * 如果该类存在一个默认构造方法,则它包含在返回的数组中。
     * 如果此 Class 对象表示一个接口、一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。
     */
    @CallerSensitive
    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
    }

    /**
     * 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。可以访问私有变量
     * name 参数是一个 String,它指定所需字段的简称。注意,此方法不反映数组类的 length 字段。
     */
    @CallerSensitive
    public Field getDeclaredField(String name)throws NoSuchFieldException, SecurityException{
    }

    /**
     * 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
     * name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组,
     * 它按声明顺序标识该方法的形参类型。如果在某个类中声明了带有相同参数类型的多个方法,
     * 并且其中有一个方法的返回类型比其他方法的返回类型都特殊,则返回该方法;否则将从中任选一个方法。
     * 如果名称是 "<init>” 或 “<clinit>",则引发一个 NoSuchMethodException。
     */
    @CallerSensitive
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException{
    }

    /**
     * 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。
     * parameterTypes 参数是 Class 对象的一个数组,它按声明顺序标识构造方法的形参类型。
     * 如果此 Class 对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例。
     */
    @CallerSensitive
    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {
    }


    /**
     *  查找具有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。
     *  此方法委托此对象的类加载器。如果此对象通过引导类加载器加载,
     *  则此方法将委托给 ClassLoader.getSystemResourceAsStream(java.lang.String)。
     *  与方法getResource()作用一样不够返回的是InputStream
     */
    public InputStream getResourceAsStream(String name) {
    }

    /**
     *  查找具有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。
     *  此方法委托此对象的类加载器。如果此对象通过引导类加载器加载,
     *  则此方法将委托给 ClassLoader.getSystemResourceAsStream(java.lang.String)。
     */
    public java.net.URL getResource(String name) {
    }

    /**
     * 返回该类的 ProtectionDomain。
     * 如果安装了安全管理器,则此方法首先通过 RuntimePermission("getProtectionDomain")
     * 权限调用安全管理器的 checkPermission 方法,以确保可以获取 ProtectionDomain。
     */
    public java.security.ProtectionDomain getProtectionDomain() {
    }

    /**
     * 如果要在调用此方法时将要初始化该类,则返回将分配给该类的断言状态。
     * 如果已经设置了该类的断言状态,则返回其最新设置;
     * 如果有包默认断言状态属于此类,则返回最特殊的相关包默认断言状态的最新设置;
     * 如果该类不是系统类(即它有类加载器),则返回其类加载器的默认断言状态;
     * 否则返回系统类默认断言状态。
     * 很少有程序员需要此方法;它是为 JRE 自身提供的。(它使类能够在初始化时确定是否启用断言。)
     * 注意,不保证此方法在(或将要)初始化指定类时返回与(或将与)该指定类相关的实际断言状态。
     */
    public boolean desiredAssertionStatus() {
    }

    /**
     * 当且仅当该类声明为源代码中的枚举时返回 true。
     */
    public boolean isEnum() {
    }

    /**
     * 如果此 Class 对象不表示枚举类型,则返回枚举类的元素或 null。
     * 以声明顺序返回一个数组,该数组包含构成此 Class 对象所表示的枚举类的值,或者在此 Class 对象不表示枚举类型时返回 null
     */
    public T[] getEnumConstants() {
    }

    /**
     * 将一个对象强制转换成此 Class 对象所表示的类或接口
     */
    @SuppressWarnings("unchecked")
    public T cast(Object obj) {
    }

    /**
     * 强制转换该 Class 对象,以表示指定的 class 对象所表示的类的一个子类。
     * 检查强制转换的有效性,如果无效则抛出 ClassCastException。如果此方法成功了,它将始终返回对此 class 对象的一个引用。
     * 此方法的使用场合为:客户端需要“收缩转换” Class 对象的类型,以便将其传递给某个 API,
     * 且该 API 对它愿意接受的 Class 对象进行限制。
     * 强制转换会产生一个编译时警告,因为强制转换的正确性无法在运行时检查(因为常规类型是通过擦除实现的)。
     */
    @SuppressWarnings("unchecked")
    public <U> Class<? extends U> asSubclass(Class<U> clazz) {
    }

    /**
     * 从接口 AnnotatedElement 复制的描述
     * 如果存在该元素的指定类型的注解,则返回这些注解,否则返回 null
     */
    @SuppressWarnings("unchecked")
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
    }

    /**
     * 如果指定类型的注解存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注解而设计的。
     */
    @Override
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
    }

    /**
     * 从接口 AnnotatedElement 复制的描述返回此元素上存在的所有注解。
     * (如果此元素没有注释,则返回长度为零的数组。)
     * 该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
     */
    public Annotation[] getAnnotations() {
    }
    
    /**
     * 从接口 AnnotatedElement 复制的描述
     * 返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释。
     * (如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;
     * 这不会对其他调用者返回的数组产生任何影响。
     * @return
     */
    public Annotation[] getDeclaredAnnotations()  {
    }

}

从方法的描述中,我们可以看出主要是一些获取Method ,Feild, Constructor的操作,包括获取所有,获取指定名称(其中又包括只能获取公共的或者全部的)外加一些类型的判断,诸如判断某个class是否是另一个class以及是否是指定的类型等方法。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

了解了Class对象,现在就可以看看 Constructor, Field, Method对象了

首先是Constructor 对象

1、作用:如果指定的类中没有空参数的构造函数,或者要创建的类对象需要通过指定的构造函数进行初始化。这时怎么办呢?这时就不能使用Class类中的newInstance方法了。既然要通过指定的构造函数进行对象的初始化。就必须先获取这个构造函数——Constructor。Constructor代表某个类的构造方法。

2、获取构造方法: 假设Person有一个默认构造方法和一个 Person(String name,Integer age)构造方法
        1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法
              Constructor[] cons = Class.forName("类的全限定名").getConstructors();
        2)获取某一个构造方法:
              Constructor con=Person.class.getConstructor(String.class,int.class);
3、创建实例对象:
        1)通常方式:Person p = new Person("lisi",30);
        2)反射方式:Person p= (Person)con.newInstance("lisi",30);
注:
        1、创建实例时newInstance方法中的参数列表必须与获取Constructor的方法getConstructor方法中的参数列表一致。
        2、newInstance():构造出一个实例对象,每调用一次就构造一个对象。
        3、利用Constructor类来创建类实例的好处是可以指定构造函数,而Class类只能利用无参构造函数创建类实例对象。

/**
 * Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
 * Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换,
 * 但是如果发生收缩转换,则抛出 IllegalArgumentException。
 */
public final class Constructor<T> extends Executable {


    /**
     * 返回 Class 对象,该对象表示声明由此 Constructor 对象表示的构造方法的类。
     */
    @Override
    public Class<T> getDeclaringClass() {
        return clazz;
    }

    /**
     * 以字符串形式返回此构造方法的名称。它总是与构造方法的声明类的简单名称相同。
     */
    @Override
    public String getName() {
        return getDeclaringClass().getName();
    }

    /**
     * 以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。应该使用 Modifier 类对这些修饰符进行解码
     */
    @Override
    public int getModifiers() {
        return modifiers;
    }

    /**
     * 按照声明顺序返回一组 TypeVariable 对象,这些对象表示通过此 GenericDeclaration 对象所表示的一般声明来声明的类型变量。
     * 如果底层一般声明未声明任何类型的变量,则返回一个长度为 0 的数组。
     */
    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public TypeVariable<Constructor<T>>[] getTypeParameters() {
    }


    /**
     * 按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。
     * 如果底层构造方法不带任何参数,则返回一个长度为 0 的数组。
     */
    @Override
    public Class<?>[] getParameterTypes() {
        return parameterTypes.clone();
    }

    /**
     * 得到参数的数量
     */
    public int getParameterCount() { return parameterTypes.length; }

    /**
     * 按照声明顺序返回一组 Type 对象,这些对象表示此 Constructor 对象所表示的方法的形参类型。
     * 如果底层方法不带任何参数,则返回一个长度为 0 的数组。
     * 如果形参类型是一个参数化类型,那么为它返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。
     * 如果形参类型是一个类型变量或者是一个参数化类型,则创建它。否则将解析它。
     */
    @Override
    public Type[] getGenericParameterTypes() {
        return super.getGenericParameterTypes();
    }

    /**
     * 返回一组表示声明要抛出的异常类型的 Class 对象,这些异常是由此 Constructor 对象表示的底层构造方法抛出的。
     * 如果该构造方法声明其 throws 子句中没有任何异常,则返回一个长度为 0 的数组。
     */
    @Override
    public Class<?>[] getExceptionTypes() {
        return exceptionTypes.clone();
    }


    /**
     * 返回一组 Type 对象,这些对象表示声明要由此 Constructor 对象抛出的异常。
     * 如果底层方法声明其 throws 子句中没有任何异常,则返回一个长度为 0 的数组。
     * 如果异常类型是一个参数化类型,那么为它返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。
     * 如果异常的类型是一个类型变量或是一个参数化类型,则创建它。否则将解析它。
     */
    @Override
    public Type[] getGenericExceptionTypes() {
        return super.getGenericExceptionTypes();
    }

    /**
     * 将此 Constructor 对象与指定的对象进行比较。如果对象相同,则返回 true。
     * 如果由相同的类声明并且具有相同的形参类型,那么这两个 Constructor 对象是相同的。
     */
    public boolean equals(Object obj) {
    }

    /**
     * 返回此 Constructor 的哈希码。该哈希码与底层构造方法的声明类名的哈希码相同。
     */
    public int hashCode() {
        return getDeclaringClass().getName().hashCode();
    }

    /**
     * 返回描述此 Constructor 的字符串。该字符串是作为构造方法访问修饰符(如果有)格式化的,其后面是声明类的完全限定名,
     * 再往后是构造方法形参类型的加括号的、逗号分隔的列表。
     */
    public String toString() {
    }

    /**
     * 返回描述此 Constructor 的字符串,其中包括类型参数。
     * 该字符串是作为构造方法访问修饰符(如果有)格式化的,其后面是构造方法的类型参数(如果有)的加尖括号的、逗号分隔的列表,
     * 再往后是声明类的完全限定名,再往后是该构造方法的一般形参类型的加括号的、逗号分隔的列表。
     * 空格用来分隔访问修饰符与访问修饰符,以及访问修饰符与类型参数或返回值。如果没有类型参数,则省略类型参数列表;
     * 如果存在类型参数列表,则用空格分隔列表与类名。如果声明构造方法抛出异常,则参数列表后跟着一个空格,再往后是单词 "throws" ,
     * 再往后是用逗号分隔的所抛出异常类型的列表。
     * 构造方法唯一可能的修饰符是访问修饰符 public、protected 或 private。
     * 这些修饰符只能出现一个,或者一个也不出现(如果构造方法具有默认(包)访问权)。
     * @return
     */
    @Override
    public String toGenericString() {
        return sharedToGenericString(Modifier.constructorModifiers(), false);
    }

    /**
     * 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
     * 个别参数会自动解包,以匹配基本形参,必要时,基本参数和引用参数都要进行方法调用转换。
     * 如果底层构造方法所需形参数为 0,则所提供的 initargs 数组的长度可能为 0 或 null。
     * 如果构造方法的声明类是非静态上下文的内部类,则构造方法的第一个参数需要是封闭实例;
     * 如果所需的访问检查和参数检查获得成功并且实例化继续进行,这时构造方法的声明类尚未初始化,则初始化这个类。
     * 如果构造方法正常完成,则返回新创建且已初始化的实例。
     */
    @CallerSensitive
    public T newInstance(Object ... initargs)

    }

    /**
     * 如果声明此构造方法可以带可变数量的参数,则返回 true;否则返回 false。
     */
    @Override
    public boolean isVarArgs() {
        return super.isVarArgs();
    }

    /**
     * 如果此构造方法是一个复合构造方法,则返回 true;否则返回 false。
     */
    @Override
    public boolean isSynthetic() {
        return super.isSynthetic();
    }

    /**
     * 如果存在该元素的指定类型的注解,则返回这些注释,否则返回 null。
     */
    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
        return super.getAnnotation(annotationClass);
    }

    /**
     * 返回直接存在于此元素上的所有注解。
     * 与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)
     * 该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
     */
    public Annotation[] getDeclaredAnnotations()  {
        return super.getDeclaredAnnotations();
    }

    /**
     * 按照声明顺序返回一组数组,这些数组表示通过此 Constructor 对象表示的方法的形参上的注解。
     * (如果底层方法没有参数,则返回一个长度为零的数组。
     * 如果该方法有一个或多个参数,则为每个不带注释的参数返回一个长度为零的嵌套数组。)
     * 包含在返回数组中的注释对象是可序列化的。
     * 此方法的调用者可以自由地修改返回的数组;它对返回给其他调用者的数组没有影响。
     */
    @Override
    public Annotation[][] getParameterAnnotations() {
        return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
    }
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

接下来在看看 Field 对象

Field类
Field类中定义了一些方法,可以用来查询字段的类型以及设置或读取字段的值。将这些方法与继承而来的member方法结合在一起.就可以使我们能够找出有关字段声明的全部信息,并且能够操纵某个特定对象或类的字段。
getGenericType方法返回表示字段的声明类型的Type实例。对于像String或int这样的平凡类型,该方法将返回与其相关联的Class对象,例如String.class和int.classo对于像List < Stri ng>这样的参数化类型,该方法将返回Parameterizedrype的实例,例如,对像T这样的类型,该方法将返回Typevariable实例。
遗留下来的getType方法将返回字段的类型的Class对象。对于平凡类型,该方法的行为与getGenericType方法的相同。如果字段的声明类型是参数化类型,那么getType方法将返回参数化类型的擦除所对应的Class对象,即原始类型的Class对象。例如,对于声明为List < Stri ng>的对象,getType将返回Li St. class的。如果字段的声明类型是类型变量,那么getType方法将返回类型变量的擦除所对应的class对象。例如,假设有一个类FOO<丁>,对于其声明为T类型的字段,get丁ype将返回object.
class对象。如果FOO被声明为FOo<下extends Number >,那么get下ype将返回 Number.class.
我们可以使用isEnumConstant方法查询一个字段是否是枚举常量,也可以使用get和set方法来获取和设置字段的值。这些接受object引元并返回Obj ect值的方法都有一种通用形式,以及一些可以直接处理基本类型的更加特化的形式。所有这些方法都要接受一个引元,用来指定所要操作的对象。对于静态字段,将忽略这个对象引元,所以此时也可以将其设
置为null。下面的方法将打印一个对象的short型字段的值:

public static void printShortField(Object o, String name)throws NoSuchFieldException,IllegalAccessException{
	Field field=o.getClass().getField(name);
	short value=(Short) field.get(o);
	System.out.println(value);
}
get方法的返回值可以是这个字段所引用的任何对象,如果该字段是基本类型,那么该方法将返回恰当类型的包装器类对象。对于我们的”hort型字段,get方法将返回包含该字段值的short类型的对象,而在将它赋值给本地变量value时,该对象值会自动进行拆箱转换。
set方法的使用也是类似的。将short型字段设置为所提供的值的方法看起来可能像下面这样:
public static void setShortField(Object o,String name,short nv)throws NoSuchFieldException,IllegalAccessException{
	Field field=0.getClass().getField(name);
	field .set(o .nv);
}
虽然set接受的是Object类型的参数,但是我们可以直接传递一个short型的值,并用包装转换将其包装为short类型的对象。
在上面的方法中,如果指定对象的域是不可访问的,并且这种访问权限控制是强制执行的,那么就会抛出IllegalACcessException异常;如果传递的对象与该域的类型不同,就会抛出illegalArgumentException异常;如果该域是非静态的且传递的对象引用是null,就会抛出NullPointerException异常;访问静态域可能会要求对类进行初始化,所以该方法也会抛出ExceptionInInitializerError异常。
Field类还有特定的用来获取和设置基本类型的方法,例如,我们可以在Field对象上调用getPrimitive7ype和set Primitive7ype,其中Primitive7ype是(首字母大写的)基本类型名。get方法可用于下面的语句:
short value=field.getshort(o);
而set方法可用于下面的语句:
short value=field.getshort(o);
用以上两种方式声明的语句中可以避免使用包装器类对象。Field类实现了AnnotatedElement接口,所以我们也可以像16.2节那样查询应用于域上的注解。
凭借上面介绍的方法,我们可以将Field对象用作操纵任意值的一种方式,但是我们应该尽量避免使用它。因为Java语言会在程序的编译期尽可能多地捕获编程错误,所以在我们编写代码时,使用的诸如「ield对象这样的间接方法越少,那么在将它们编译成代码之前,就可以防止更多的错误。而且,我们可以看到,在前面的代码中,要想知道到底会发生什么,与在普通的语法中直接使用域名的情况相比,我们花费在阅读代码上的精力显然大了许多。
Final字段
在通常情况下,对声明为final的字段进行设置将会导致抛出IllegalACcessException
异常,这是我们所能预期的,因为final字段的值是永远不会改变的。但是有些特殊情况—例如在定制的反序列化(见20.8.4节)中,改变final字段的值就是有意义的,我们只有在实例字段上才能通过反射实现这一点,并且前提是在该Field对象上已经调用过了setAccessible(true)。注意,可以成功调用setAccessible(true)是不够的,必须确实调用过它。
这种能力是为高度特化的上下文提供的,并非用于通用目的,我们介绍它仅仅是为了保持内容的完整性。如果脱离了特定的上下文,例如定制的反序列化,那么改变final字段的值可能会导致意外的甚至是灾难性的后果。在这些上下文之外,不能保证对final字段的改变是可见的。即便是在这样的上下文中,在使用这项技术编码时也必须保证安全机制不会阻碍代码的执行。改变值为常量变量(见2.2.3节)的final字段将会导致此改变不可见,除非通过使用反射来实现这种修改。

/**
 * Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。
 * Array 允许在执行 get 或 set 访问操作期间进行扩展转换,但如果将发生收缩转换,则抛出一个 IllegalArgumentException。
 */
public final class Field extends AccessibleObject implements Member {

    /**
     * 返回表示类或接口的 Class 对象,该类或接口声明由此 Field 对象表示的字段。
     */
    public Class<?> getDeclaringClass() {
        return clazz;
    }

    /**
     * 返回此 Field 对象表示的字段的名称。
     */
    public String getName() {
        return name;
    }

    /**
     * 以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。应该使用 Modifier 类对这些修饰符进行解码。
     */
    public int getModifiers() {
        return modifiers;
    }

    /**
     * 如果此字段表示枚举类型的元素,则返回 true;否则返回 false。
     */
    public boolean isEnumConstant() {
        return (getModifiers() & Modifier.ENUM) != 0;
    }

    /**
     * 如果此字段是复合字段,则返回 true;否则返回 false。
     */
    public boolean isSynthetic() {
        return Modifier.isSynthetic(getModifiers());
    }

    /**
     * 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
     */
    public Class<?> getType() {
        return type;
    }

    /**
     * 返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。
     * 如果 Type 是一个参数化类型,则返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。
     * 如果底层字段的类型是一个类型变量或者是一个参数化类型,则创建它。否则将解析它。
     */
    public Type getGenericType() {
    }


    /**
     * 将此 Field 与指定对象比较。如果对象是相同的,则返回 true。
     * 如果由相同的类声明并且具有相同的名称和类型,那么这两个 Field 对象是相同的。
     */
    public boolean equals(Object obj) {
    }

    /**
     *返回该 Field 的哈希码。这作为底层字段的声明类名及其名称的哈希码的异或进行计算。
     */
    public int hashCode() {
        return getDeclaringClass().getName().hashCode() ^ getName().hashCode();
    }

    /**
     * 返回一个描述此 Field 的字符串。格式是:该字段(如果存在的话)的访问修饰符,后面跟着字段类型和一个空格,
     * 再后面是声明该字段的类的完全限定名,后面跟着一个句点,最后是字段的名称
     */
    public String toString() {
    }

    /**
     * 返回一个描述此 Field(包括其一般类型)的字符串。格式是:该字段(如果存在的话)的访问修饰符,
     * 后面跟着一般字段类型和一个空格,再后面是声明该字段的类的完全限定名,后面跟着一个句点,最后是字段的名称。
     */
    public String toGenericString() {
    }

    /**
     * 返回指定对象上此 Field 表示的字段的值。如果该值是一个基本类型值,则自动将其包装在一个对象中。
     * 底层字段的值是按以下方式获得的:
     * 如果底层字段是一个静态字段,则忽略 obj 变量;它可能为 null。
     * 否则,底层字段是一个实例字段。如果指定的 obj 变量为 null,则该方法将抛出一个 NullPointerException。
     * 如果指定对象不是声明底层字段的类或接口的实例,则该方法将抛出一个 IllegalArgumentException。
     * 如果此 Field 对象强制实施 Java 语言访问控制,并且底层字段是不可访问的,则该方法将抛出一个 IllegalAccessException。
     * 如果底层字段是静态的,并且声明该字段的类尚未初始化,则初始化这个类。
     * 否则,从底层实例字段或静态字段中获取该值。如果该字段是一个基本类型字段,则在返回前将该值包装在一个对象中,否则照原样返回。
     * 如果字段隐藏在 obj 的类型中,则根据前面的规则获得字段的值。
     *
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 boolean 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 byte 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 char 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 short 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException {

    }

    /**
     * 获取一个静态或实例 int 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public int getInt(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 long 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 float 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 获取一个静态或实例 double 字段的值。
     * obj 从中提取 属性 值的对象
     */
    @CallerSensitive
    public double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。如果底层字段的类型为基本类型,则对新值进行自动解包。
     * 进行此操作的方式如下:
     * 如果底层字段是静态字段,则忽略 obj 变量;它可能为 null。
     * 否则底层字段是一个实例字段。如果指定对象变量为 null,则该方法将抛出一个 NullPointerException。
     * 如果指定对象变量不是声明底层字段的类或接口的实例,则该方法将抛出一个 IllegalArgumentException。
     * 如果此 Field 对象实施 Java 语言访问控制,并且底层字段是不可访问的,则该方法将抛出一个 IllegalAccessException。
     * 如果底层字段为 final 字段,则该方法将抛出一个 IllegalAccessException,
     * 除非 setAccessible(true) 已经继承该字段并且该字段是一个非静态字段。
     * 在通过程序的其他部分可以访问类的实例之前,只有使用空白 final 字段反序列化或重构类的实例期间,
     * 以这种方式设置 final 字段才有意义。在其他任何上下文中使用该方法都可能会有不可预知的结果,
     * 包括程序的其他部分继续使用该字段的原始值的情况。
     * 如果底层字段的类型为某一基本类型,则可以尝试使用解包转换将新值转换为基本类型的值。
     * 如果该尝试失败,则此方法将抛出一个 IllegalArgumentException。
     * 如果在进行可能的解包之后,无法通过某一标识或扩展转换将新值转换为底层字段的类型,
     * 则此方法将抛出一个 IllegalArgumentException。
     * 如果底层字段是静态的,并且声明该字段的类尚未初始化,则初始化这个类。
     * 字段被设置为可能已解包并扩大的新值。
     * 如果字段隐藏在 obj 的类型中,则根据前面的规则设置字段的值。
     */
    @CallerSensitive
    public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException {
    }

    /**
     * 同时Field方法还提供针对原始类型的设值函数此处省略
     */
}
主要的相关方法如下
        Field getField(String s); // Class的方法 只能获取公有和父类中公有  
        Field getDeclaredField(String s); // Class的方法 获取该类中任意成员变量,包括私有
setAccessible(ture); // Class的方法 如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。
set(Object obj, Object value); //将指定对象变量上此Field对象表示的字段设置为指定的新值。
Object get(Object obj); //返回指定对象上Field表示的字段的值。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
最后再来看看Method方法

/**
 * Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
 * 所反映的方法可能是类方法或实例方法(包括抽象方法)。Method 允许在匹配要调用的实参与底层方法的形参时进行扩展转换;
 * 但如果要进行收缩转换,则会抛出 IllegalArgumentException。
 * Method类和它从Member类继承而来的方法使得我们可以获得方法声明的完整信息
 * 同时Method还提供了invoke方法供我们调用该方法的执行费
 */
public final class Method extends Executable {

    /**
     * 返回表示声明由此 Method 对象表示的方法的类或接口的 Class 对象。
     */
    @Override
    public Class<?> getDeclaringClass() {
        return clazz;
    }

    /**
     * 以 String 形式返回此 Method 对象表示的方法名称。
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * 以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符。应该使用 Modifier 类对修饰符进行解码。
     */
    @Override
    public int getModifiers() {
        return modifiers;
    }

    /**
     * 返回 TypeVariable 对象的数组,这些对象描述了由 GenericDeclaration 对象表示的一般声明按声明顺序来声明的类型变量。
     * 如果底层一般声明没有声明类型变量,则返回长度为 0 的数组。
     */
    @Override
    @SuppressWarnings({"rawtypes", "unchecked"})
    public TypeVariable<Method>[] getTypeParameters() {
    }

    /**
     * 返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。
     */
    public Class<?> getReturnType() {
        return returnType;
    }

    /**
     * 返回表示由此 Method 对象所表示方法的正式返回类型的 Type 对象。
     * 如果返回类型是参数化类型,则返回的 Type 对象必须实际反映源代码中所用参数的实际类型。
     * 如果返回类型是类型变量或参数化类型,则创建它。否则将解析它。
     */
    public Type getGenericReturnType() {
    }

    /**
     * 按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。
     * 如果底层方法不带参数,则返回长度为 0 的数组。
     */
    @Override
    public Class<?>[] getParameterTypes() {
        return parameterTypes.clone();
    }

    /**
     * 返回方法中的参数数量
     */
    public int getParameterCount() { return parameterTypes.length; }


    /**
     * 按照声明顺序返回 Type 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型的。
     * 如果底层方法不带参数,则返回长度为 0 的数组。
     *
     * 如果形参类型是参数化类型,则为其返回的 Type 对象必须实际反映源代码中使用的实际类型参数。
     * 如果形参类型是类型变量或参数化类型,则创建它。否则将解析它。
     */
    @Override
    public Type[] getGenericParameterTypes() {
        return super.getGenericParameterTypes();
    }

    /**
     * 返回 Class 对象的数组,这些对象描述了声明将此 Method 对象表示的底层方法抛出的异常类型。
     * 如果此方法没有在其 throws 子句中声明异常,则返回长度为 0 的数组。
     */
    @Override
    public Class<?>[] getExceptionTypes() {
        return exceptionTypes.clone();
    }

    /**
     * 返回 Type 对象数组,这些对象描述了声明由此 Method 对象抛出的异常。如果底层方法没有在其 throws 子句中声明异常,
     * 则返回长度为 0 的数组。
     *
     * 如果异常类型是参数化的类型,那么为它返回的 Type 对象必须实际反映源代码中所用参数的实际类型。
     * 如果异常类型是类型变量或参数化类型,则创建它。否则将解析它。
     */
    @Override
    public Type[] getGenericExceptionTypes() {
        return super.getGenericExceptionTypes();
    }

    /**
     * 将此 Method 与指定对象进行比较。如果对象相同,则返回 true。
     * 如果它们由相同的类声明,具有相同的名称、形参类型和返回类型,则两个 Method 相同。
     */
    public boolean equals(Object obj) {

    }

    /**
     * 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。个别参数被自动解包,以便与基本形参相匹配,
     * 基本参数和引用参数都随需服从方法调用转换。
     *
     * 如果底层方法是静态的,那么可以忽略指定的 obj 参数。该参数可以为 null。
     * 如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。
     * 如果底层方法是实例方法,则使用动态方法查找来调用它,在发生基于目标对象的运行时类型的重写时更应该这样做。
     * 如果底层方法是静态的,并且尚未初始化声明此方法的类,则会将其初始化。
     * 如果方法正常完成,则将该方法返回的值返回给调用者;如果该值为基本类型,则首先适当地将其包装在对象中。
     * 但是,如果该值的类型为一组基本类型,则数组元素不 被包装在对象中;换句话说,将返回基本类型的数组。
     * 如果底层方法返回类型为 void,则该调用返回 null。
     */
    @CallerSensitive
    public Object invoke(Object obj, Object... args)
    }

    /**
     * 如果此方法是 bridge 方法,则返回 true;否则,返回 false。
     */
    public boolean isBridge() {
        return (getModifiers() & Modifier.BRIDGE) != 0;
    }

    /**
     * 如果将此方法声明为带有可变数量的参数,则返回 true;否则,返回 false。
     */
    @Override
    public boolean isVarArgs() {
        return super.isVarArgs();
    }

    /**
     * 如果此方法为复合方法,则返回 true;否则,返回 false。
     */
    @Override
    public boolean isSynthetic() {
        return super.isSynthetic();
    }

    /**
     * 判断此方法是否为default方法
     */
    public boolean isDefault() {

    }

    /**
     * 返回由此 Method 实例表示的注释成员的默认值。
     * 如果该成员为基本类型,则返回相应包装器类型的实例。
     * 如果不存在与该成员关联的默认值或者该成员实例不表示注释类型的声明成员,则返回 null。
     */
    public Object getDefaultValue() {
    }
    
    /**
     * 返回表示按照声明顺序对此 Method 对象所表示方法的形参进行注释的那个数组的数组。
     * (如果底层方法没有参数,则返回长度为零的数组。如果该方法有一个或多个参数,则为每个不带注释的参数返回长度为零的嵌套数组。)
     * 返回数组中包含的注释对象是可序列化的。此方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。
     */
    @Override
    public Annotation[][] getParameterAnnotations() {
        return sharedGetParameterAnnotations(parameterTypes, parameterAnnotations);
    }
    
}

以上就是反射的基础知识了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值