Class类及相关类解读

Class类及相关类解读

一、简介

在看各种开源项目源码时,可以发现,越偏框架偏下层的,代码越是直接基于反射面向Class编程。在实际开发过程中,合理的使用Class编程,可以大幅减少代码量。基于此,这里对Class类及相关类的源码进行解读。

二、Class类结构

2.1 类实例

Class类的完整类名是java.lang.Class。Class实例表示运行中java程序的类或接口。枚举Enum是一种类,注解Annotation是一种接口,数组也是属于有相同元素组成的类。基本类型boolean、byte、char、shot、int、long、fload、double以及关键字void也表示类实例。

2.2 类加载

类没有公开的构造器,当虚拟机加载或被类定义方法(如Class.forName(String className)调用时,类实例自动构造。类的加载采用双亲委派模型。
加载流程为:

自定义类加载器
应用类加载器
扩展类加载器
启动类加载器

具体流程为:当类加载器收到类加载请求时,刚开始不会自己加载,而是让其父类加载器加载,一直到最顶层启动类加载器加载,若还是无法加载,再从上往下让子类加载器尝试加载,流程同前类似。

2.3 类定义

Class类实现了接口java.lang.reflect.Type、java.lang.reflect.AnnotatedElement、java.lang.reflect.GenericDeclaration接口,以及泛型T。

public final class Class<T> implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {...}
2.3.1 java.lang.reflect.Type

Type是java所有类型(包含原始类型raw types、参数化类型parameterized types、数组类型array types、类型变量type variables、基本类型primitive types)公共的父接口。
接口定义如下:

public interface Type {
    //类型描述
    default String getTypeName() {
        return toString();
    }
}

Type接口实现类图如下:

TypeVariable表示类型变量,如:List,这里的T就是类型变量;
ParameterizedType表示参数化类型,如:List;
GenericArrayType表示泛型数组类型,如:List[]或T[];
WildcardType表示通配符类型,如:List<? extends Number>或List<? super Intger>;

示例:

public class TypeStudy {
    public static void main(String[] args) {
        //获取类实例的描述,输出:com.dragon.study.study20190618.classStudy.ClassStudy$Person
        String typeName = Person.class.getTypeName();
    }
    public static class Person {
    }
}

备注:关于泛型类型的操作,后面在单独博客中介绍。

2.3.2 java.lang.reflect.AnnotatedElement

AnnotatedElement表示jvm运行中的注解类型。通过反射可以获取类的注解信息。接口定义如下:

public interface AnnotatedElement {
    //是否存在指定类型的注解
    default boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {..}
    //获取指定类型的注解
    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
    //获取注解数组
    Annotation[] getAnnotations();
    //获取指定类型注解数组
    default <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {..}
    //获取指定类型注解(不包含继承)
    default <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {...}
    //获取指定类型所有注解(不包含继承)
    default <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotationClass) {...}
    //获取所有注解(不包含继承)
    Annotation[] getDeclaredAnnotations();
}

示例:

import java.lang.annotation.*;
public class AnnotationElementStudy {
    public static void main(String[] args) {
        //获取注解数组,返回注解数组为BaseAnnotation、AnnotationOne、AnnotationTwo
        Annotation[] annotations = Stu.class.getAnnotations();

        //获取指定类型注解数组,返回注解为AnnotationOne
        Annotation[] annotationsByType = Stu.class.getAnnotationsByType(AnnotationOne.class);

        //获取指定类型的注解,返回注解为AnnotationTwo
        AnnotationTwo annotation = Stu.class.getAnnotation(AnnotationTwo.class);

        //是否存在指定类型的注解,结果为true
        boolean presentTwo = Stu.class.isAnnotationPresent(AnnotationTwo.class);
        //结果为false
        boolean presentThree = Stu.class.isAnnotationPresent(AnnotationThree.class);

        //获取所有注解(不包含继承),返回注解数组为AnnotationOne、AnnotationTwo
        Annotation[] declaredAnnotations = Stu.class.getDeclaredAnnotations();

        //获取指定类型所有注解(不包含继承),返回注解数组为AnnotationOne
        Annotation[] declaredAnnotationsByType = Stu.class.getDeclaredAnnotationsByType(AnnotationOne.class);

        //获取指定类型注解(不包含继承),返回注解数组为AnnotationOne
        AnnotationOne annotationOne = Stu.class.getDeclaredAnnotation(AnnotationOne.class);
    }

    //定义Person类
    @AnnotationThree
    @BaseAnnotation(base = 1)
    public static class Person {}

    //定义Stu类
    @AnnotationOne
    @AnnotationTwo
    public static class Stu<Integer, String> extends Person {}

    //定义BaseAnnotation注解
    @Inherited  //指定该注解可以被继承
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BaseAnnotation {
        int base() default 1;
    }

    //定义AnnotationOne注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AnnotationOne {
        int one() default 10;
    }

    //定义AnnotationTwo注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AnnotationTwo {
        int two() default 10;
    }

    //定义AnnotationThree注解
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AnnotationThree {
        int three() default 10;
    }
}

备注:
如果注解需要被继承,则定义父注解时需要加上@Inherited(标识该注解可以被继承)

2.3.3 java.lang.reflect.GenericDeclaration

GenericDeclaration表示声明类型变量的所有实体的公共接口,也就是哪些实体可以声明泛型。在jdk中目前只有Class、Method、Constructor实现了GenericDeclaration接口,也就是三个类可以声明泛型,类图如下
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hCucxeQU-1572677519302)(http://www.plantuml.com/plantuml/png/oymhIIrAIqnELN1FpKijoansIKtEIInABCdCp-DAJ2ekAKfCBb402XKNAxXMf2QNbYGcvQHoGGHyKqioybEW7EVyFA3gqkII_2AO28ZauW9J2dgb1NerTjXiGHYBHn74AWNTqW9Te08abo1PYqKM0000)]

GenericDeclaration定义如下:

public interface GenericDeclaration extends AnnotatedElement {
    //依序返回类型变量(泛型中定义的)的数组,若没有则返回长度为0的数组
    public TypeVariable<?>[] getTypeParameters();
}

示例如下:

import java.lang.reflect.TypeVariable;
public class GenericDeclarationStudy {
    public static void main(String[] args) {
        //获取泛型中的类型变量,这里返回的类型为Integer、String
        TypeVariable<?>[] typeVariables = Stu.class.getTypeParameters();
    }
    //声明泛型,类型变量为Integer,String
    public static class Stu<Integer, String> {
    }
}

三、java.lang.Class方法

Class源码解读如下(这里按源码本身顺序解读):

public final class Class<T> implements java.io.Serializable,GenericDeclaration,Type,AnnotatedElement {
    //返回类描述
    public String toString() {}

    //返回类描述(包含修饰符和类型参数)
    public String toGenericString() {}

    //加载给定名称的类或接口,并返回类实例,相当于执行Class.forName(className, true, currentLoader)
    public static Class<?> forName(String className) throws ClassNotFoundException {}

    //获取给定名称的类实例,initialize标识是否初始化,loader指定类加载器
    public static Class<?> forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException{}

    //创建并返回类实例
    public T newInstance() throws InstantiationException, IllegalAccessException{}

    //指定检测对象是否是当前类实例兼容(当前类或子类)的对象
    public native boolean isInstance(Object obj);

    //检测指定类实例是否是当前类实例兼容(当前类或子类)的类实例
    public native boolean isAssignableFrom(Class<?> cls);

    //检测当前类实例是否是接口
    public native boolean isInterface();

    //检测当前类实例是否是数组
    public native boolean isArray();

    //检测当前类实例是否是基本类型(8种基本类型和void类型)
    public native boolean isPrimitive();

    //检测当前类实例是否是注解
    public boolean isAnnotation() {}

    //当前类实例是否是编译器合成的(非代码编写的),true:是  false:否
    public boolean isSynthetic() {}

    //返回类实例名称
    public String getName() {}

    //获取当前类实例的类加载器,如果由启动类加载器(bootstrap class loader)加载,则返回null
    public ClassLoader getClassLoader() {}

    //获取当前类实例的类型变量
    public TypeVariable<Class<T>>[] getTypeParameters() {}

    //获取父类实体,其中Class类型、Object类型、基本类型、void类型、接口类型则返回为null
    public native Class<? super T> getSuperclass();

    //返回直接父类Type实例(包含泛型参数)
    public Type getGenericSuperclass() {}

    //返回包实例,如果没有包实例,则返回null
    public Package getPackage() {}

    //返回当前类(类或接口)实例实现(或继承)的接口数组
    public Class<?>[] getInterfaces() {}

    //返回当前类(类或接口)实例实现(或继承)的接口Type数组(包含泛型参数)
    public Type[] getGenericInterfaces() {}

    //返回数组内单个元素的类实例,如果不是数组则返回null
    public native Class<?> getComponentType();

    //返回类实例的修饰符(类型有public/protected/private/final/static/abstract/interface)的integer编号(java.lang.reflect.Modifier中定义的)
    public native int getModifiers();

    //返回当前类实例的签名者,如果没有签名者或者基本类型或者void则返回null
    public native Object[] getSigners();

    //如果当前类实例是在方法中定义的本地或匿名类,则返回包含该类实例的方法,否则返回null
    public Method getEnclosingMethod() throws SecurityException {}

    //如果当前类实例是在构造器中定义的本地或匿名类,则返回包含该类实例的构造器,否则返回null
    public Constructor<?> getEnclosingConstructor() throws SecurityException {}

    //返回定义当前类实例的外层类实例,若没有或者当前类实例是数组、基本类型、void则返回null
    public Class<?> getDeclaringClass() throws SecurityException {}

    //返回包含(可以是类、方法、构造器等包含)当前类定义的外层类实例,如果当前类定义是最顶层则返回null
    public Class<?> getEnclosingClass() throws SecurityException {}

    //返回当前类实例的简单名称,如果是匿名类则返回空串,如果是数组则类名后会添加[]
    public String getSimpleName() {}

    //返回当前类实例的type类型的名称
    public String getTypeName() {}

    //返回当前类实例由java规范定义的名称(也就是java语言层面显示的),区别于getName(jvm层面显示的)
    public String getCanonicalName() {}

    //是否是匿名类实例
    public boolean isAnonymousClass() {}

    //是否是局部类
    public boolean isLocalClass() {}

     //是否是成员类
    public boolean isMemberClass() {}

    //返回当前类实例的公开内部类(或接口)和父类的公开内部类(或接口)构成的数组(即是包含父类中的局部类,区别于getDeclaredClasses不包含父类的内部类)
    public Class<?>[] getClasses() {}

    //返回当前类实例可访问的所有公开字段(包含父类的)
    public Field[] getFields() throws SecurityException {}

    //返回当前类实例可访问的所有公开方法(包含父类的,如Object类中的公开方法也会返回)
    public Method[] getMethods() throws SecurityException {}

    //返回当前类实例的所有公开构造器
    public Constructor<?>[] getConstructors() throws SecurityException {}

    //返回当前类实例可访问的指定字段(父类的也可以)
    public Field getField(String name) throws NoSuchFieldException, SecurityException {}

    //返回当前类实例可访问的指定方法(父类的也可以)
    public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {}

    //返回当前类实例的指定构造器
    public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {}

    //返回当前类实例的公开内部类(或接口)构成的数组(不包含父类的内部类)
    public Class<?>[] getDeclaredClasses() throws SecurityException {}

    //返回当前类实例可访问的公开字段(不包含父类的)
    public Field[] getDeclaredFields() throws SecurityException {}

    //返回当前类实例可访问的所有公开方法(不包含父类的)
    public Method[] getDeclaredMethods() throws SecurityException {}

    //返回当前类实例的所有构造器(包含public, protected, default (package) access, and private类型)
    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {}

    //返回当前类实例可访问的指定字段(不包含父类的)
    public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException {}

    //返回当前类实例可访问的指定方法(不包含父类的)
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {}

    //返回当前类实例的指定构造器(包含public, protected, default (package) access, and private类型)
    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException {}

    //返回当前类实例路径下的指定资源
    public InputStream getResourceAsStream(String name) {}

    //查找指定名称的资源,如果以"/"开头则以绝对路径查找,否则在当前类路径下找
    public java.net.URL getResource(String name) {}

    //返回当前类的ProtectionDomain
    public java.security.ProtectionDomain getProtectionDomain() {}

    //返回当前类实例的断言状态
    public boolean desiredAssertionStatus() {}

    //是否是枚举
    public boolean isEnum() {}

    //返回当前枚举实例的所有枚举
    public T[] getEnumConstants() {}

    //将指定对象转为当前类实例类型
    public T cast(Object obj) {}

    //检测当前类实例是否是指定类实例的子类,若是则返回当前类实例,若否则抛出异常ClassCastException
    public <U> Class<? extends U> asSubclass(Class<U> clazz) {}

    //获取指定类型的注解
    public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {}

    //是否存在指定类型的注解
    public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {}

    //获取指定类型注解数组
    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {}

    //获取所有注解(包含注解)
    public Annotation[] getAnnotations() {}

    //获取指定类型注解(不包含继承)
    public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {}

    //获取指定类型所有注解(不包含继承)
    public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {}

    //获取所有注解(不包含继承)
    public Annotation[] getDeclaredAnnotations()  {}

    //返回当前类实例的父类注解类型(AnnotatedType),如果当前类实例是Object、interface、array type、primary type、void则返回null
    public AnnotatedType getAnnotatedSuperclass() {}

    //返回当前类实例的实现接口的所有注解类型
    public AnnotatedType[] getAnnotatedInterfaces() {}
}

运行示例如下:

package com.study.classStudy;
import java.io.InputStream;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.net.URL;
import java.security.ProtectionDomain;

public class ClassStudyPaper {
    public static void main(String[] args) throws Exception {
        //返回类描述,如:class com.study.classStudy.ClassStudy$Stu
        String str = Stu.class.toString();

        //返回类描述(包含修饰符和类型参数),如:public static class com.study.classStudy.ClassStudy$Stu<Integer,String>
        String genericString = Stu.class.toGenericString();

        //加载给定名称的类或接口,并返回类实例
        Class<?> clazz = Class.forName("com.study.classStudy.ClassStudyPaper");

        //创建并返回类实例
        Stu stu = Stu.class.newInstance();

        //指定检测对象是否是当前类实例兼容(当前类或子类)的对象
        boolean isInstance = Stu.class.isInstance(stu); //true
        isInstance = Person.class.isInstance(stu); //true

        //检测指定类实例是否是当前类实例兼容(当前类或子类)的类实例
        boolean isAssignable = Stu.class.isAssignableFrom(Stu.class); //true
        isAssignable = Person.class.isAssignableFrom(Stu.class); //true

        //检测当前类实例是否是接口
        boolean isInterface = Eat.class.isInterface(); //true

        //检测当前类实例是否是数组
        boolean isArray = int[].class.isArray(); //true

        //检测当前类实例是否是原始类型
        boolean isPrimitive = int.class.isPrimitive(); //true
        isPrimitive = void.class.isPrimitive(); //true
        isPrimitive = Integer.class.isPrimitive();  //false
        isPrimitive = Void.class.isPrimitive(); //false

        //检测当前类实例是否是注解
        boolean isAnnotation = BaseAnnotation.class.isAnnotation(); //true

        //当前类实例是否是编译器合成的,true:是  false:否
        boolean isSynthetic = Stu.class.isSynthetic(); //false
        isSynthetic = Stu.getHobby().getClass().isSynthetic();

        //返回类实例名称, com.study.classStudy.ClassStudy$Stu
        String name = Stu.class.getName();

        //获取当前类实例的类加载器,如果由启动类加载器(bootstrap class loader)加载,则返回null
        ClassLoader classLoader = Stu.class.getClassLoader();
        ClassLoader intClassLoader = Integer.class.getClassLoader(); //null

        //获取当前类实例的类型变量
        TypeVariable<Class<Stu>>[] typeVariables = Stu.class.getTypeParameters();

        //获取父类实体, 其中Class类型、Object类型、基本类型、void类型、接口类型则返回为null
        Class<? super Stu> supperClazz = Stu.class.getSuperclass(); //class com.study.classStudy.ClassStudy$Person
        Class<?> arrSupperClazz = Stu[].class.getSuperclass(); //class java.lang.Object
        Class<?> objectSupperClazz = Object.class.getSuperclass(); //null
        Class<?> intSupperClazz = int.class.getSuperclass(); // null
        Class<?> voidSupperClazz = void.class.getSuperclass(); //null
        Class<?> eatSupperClazz = Eat.class.getSuperclass(); //null
        Class<?> classSupperClazz = Class.class.getSuperclass(); //null

        //返回直接父类Type实例(包含泛型参数),com.study.classStudy.ClassStudy$Person<String>
        Type genericSuperclass = Stu.class.getGenericSuperclass();

        //返回包实例
        Package pac = Stu.class.getPackage(); //package com.study.classStudy

        //返回当前类(类或接口)实例实现(或继承)的接口数组
        Class<?>[] interfaces = Stu.class.getInterfaces();   //包含Drink接口的数组

        //返回当前类(类或接口)实例实现(或继承)的接口Type数组(包含泛型参数)
        Type[] genericInterfaces = Stu.class.getGenericInterfaces();   //包含Drink接口的数组

        //返回数组内单个元素的类实例,如果不是数组则返回null
        Class<?> intArrcomponentType = Integer[].class.getComponentType();  //class java.lang.Integer
        Class<?> stuComponentType = Stu.class.getComponentType();  //null

        //返回类实例的修饰符(类型有public/protected/private/final/static/abstract/interface)的integer编号(java.lang.reflect.Modifier中定义的)
        int modifiers = Stu.class.getModifiers();

        //返回当前类实例的签名者,如果没有签名者或者基本类型或者void则返回null
        Object[] singers = Stu.class.getSigners();

        //如果当前类实例是在方法中定义的本地或匿名类,则返回包含该类实例的方法,否则返回null
        Method enclosingMethod = Stu.getHobby().getClass().getEnclosingMethod(); //public static java.lang.Object com.study.classStudy.ClassStudy$Stu.getHobby()

        //如果当前类实例是在构造器中定义的本地或匿名类,则返回包含该类实例的构造器,否则返回null
        Constructor<?> enclosingConstructor = new Stu<>().skill.getClass().getEnclosingConstructor(); //public static java.lang.Object com.study.classStudy.ClassStudy$Stu.getHobby()

        //返回定义当前类实例的外层类实例,若没有或者当前类实例是数组、基本类型、void则返回null
        Class<?> declaringClass = Stu.class.getDeclaringClass(); //class com.study.classStudy.ClassStudy

        //返回包含(可以是类、方法、构造器等包含)当前类定义的外层类实例,如果当前类定义是最顶层则返回null
        Class<?> enclosingClass = Stu.class.getEnclosingClass(); //class com.study.classStudy.ClassStudy
        enclosingClass = Stu.getHobby().getClass().getEnclosingClass(); //class com.study.classStudy.ClassStudy$Stu

        //返回当前类实例的简单名称,如果是匿名类则返回空串,如果是数组则类名后会添加[]
        String simpleName = Stu.class.getSimpleName(); //Stu
        simpleName = Stu[].class.getSimpleName(); //Stu[]

        //返回当前类实例的type类型的名称
        String typeName = Stu.class.getTypeName(); //com.study.classStudy.ClassStudy$Stu

        //返回当前类实例由java规范定义的名称(也就是java语言层面显示的),区别于getName(jvm层面显示的)
        String canonicalName = Stu[].class.getCanonicalName(); //com.study.classStudy.ClassStudy.Stu[]
        String compName = Stu[].class.getName(); //[Lcom.study.classStudy.ClassStudy$Stu;

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
            }
        };
        //是否是匿名类实例
        boolean isAnonymousClass = runnable.getClass().isAnonymousClass(); //true

        //是否是局部类
        boolean isLocalClass = Stu.getHobby().getClass().isLocalClass(); //true

        //是否是成员类
        boolean isMemberClass = Stu.class.isMemberClass(); //true

        //返回当前类实例的公开内部类(或接口)和父类的公开内部类(或接口)构成的数组(即是包含父类中的局部类,区别于getDeclaredClasses不包含父类的内部类)
        Class<?>[] clazzes = Stu.class.getClasses();//返回Stu.Think和Person.Head类

        //返回当前类实例可访问的所有公开字段(包含父类的)
        Field[] fields = Stu.class.getFields();

        //返回当前类实例可访问的所有公开方法(包含父类的,如Object类中的公开方法也会返回)
        Method[] methods = Stu.class.getMethods();

        //返回当前类实例的所有公开构造器
        Constructor<?>[] constructors = Stu.class.getConstructors();

        //返回当前类实例可访问的指定字段(父类的也可以)
        Field field = Stu.class.getField("stuName");  //public java.lang.Object com.study.classStudy.ClassStudy$Stu.stuName
        field = Stu.class.getField("age"); //public java.lang.Integer com.study.classStudy.ClassStudy$Person.age

        //返回当前类实例可访问的指定方法(父类的也可以)
        Method method = Stu.class.getMethod("setStuName", String.class); //public void com.study.classStudy.ClassStudy$Stu.setStuName(java.lang.String)
        method = Stu.class.getMethod("setAge", Integer.class); //public void com.study.classStudy.ClassStudy$Person.setAge(java.lang.Integer)

        //返回当前类实例的指定构造器
        Constructor<Stu> constructor = Stu.class.getConstructor(String.class); //public com.study.classStudy.ClassStudy$Stu(java.lang.String)

        //返回当前类实例的公开内部类(或接口)构成的数组(不包含父类的内部类)
        Class<?>[] declaredClasses = Stu.class.getDeclaredClasses();//返回Stu.Think和Person.Head类

        //返回当前类实例可访问的公开字段(不包含父类的)
        Field[] declaredFields = Stu.class.getDeclaredFields();

        //返回当前类实例可访问的所有公开方法(不包含父类的)
        Method[] declaredMethods = Stu.class.getDeclaredMethods();

        //返回当前类实例的所有构造器(包含public, protected, default (package) access, and private类型)
        Constructor<?>[] declaredConstructors = Stu.class.getDeclaredConstructors();

        //返回当前类实例可访问的指定字段(不包含父类的)
        Field declaredField = Stu.class.getDeclaredField("stuName");  //public java.lang.Object com.study.classStudy.ClassStudy$Stu.stuName

        //返回当前类实例可访问的指定方法(不包含父类的)
        Method declaredMethod = Stu.class.getDeclaredMethod("setStuName", String.class); //public void com.study.classStudy.ClassStudy$Stu.setStuName(java.lang.String)

        //返回当前类实例的指定构造器(包含public, protected, default (package) access, and private类型)
        Constructor<Stu> declaredConstructor = Stu.class.getDeclaredConstructor(Object.class); //public com.study.classStudy.ClassStudy$Stu(java.lang.String)

        //返回当前类实例路径下的指定资源
        InputStream rsStream = Stu.class.getResourceAsStream("ClassStudy.class");

        //查找指定名称的资源,如果以"/"开头则以绝对路径查找,否则在当前类路径下找
        URL url = Stu.class.getResource("ClassStudy.class");

        //返回当前类的ProtectionDomain
        ProtectionDomain protectionDomain = Stu.class.getProtectionDomain();

        //返回当前类实例的断言状态
        boolean desiredAssertionStatus = Stu.class.desiredAssertionStatus();

        //是否是枚举
        boolean isEnum = SCHOOL_TYPE.class.isEnum();

        //返回当前枚举实例的所有枚举
        SCHOOL_TYPE[] enumConstants = SCHOOL_TYPE.class.getEnumConstants();

        Object obj = 11;
        //将指定对象转为当前类实例类型
        Integer a = Integer.class.cast(obj);

        //检测当前类实例是否是指定类实例的子类,若是则返回当前类实例,若否则抛出异常ClassCastException
        Class<? extends Person> stuClass = Stu.class.asSubclass(Person.class); //class com.study.classStudy.ClassStudy$Stu

        //获取指定类型的注解,返回注解为AnnotationTwo
        AnnotationElementStudy.AnnotationTwo annotation = AnnotationElementStudy.Stu.class.getAnnotation(AnnotationElementStudy.AnnotationTwo.class);

        //是否存在指定类型的注解,结果为true
        boolean presentTwo = AnnotationElementStudy.Stu.class.isAnnotationPresent(AnnotationElementStudy.AnnotationTwo.class);

        //获取所有注解(包含注解),返回注解数组为BaseAnnotation、AnnotationOne、AnnotationTwo
        Annotation[] annotations = AnnotationElementStudy.Stu.class.getAnnotations();


        //获取指定类型注解(不包含继承),返回注解数组为AnnotationOne
        AnnotationElementStudy.AnnotationOne annotationOne = AnnotationElementStudy.Stu.class.getDeclaredAnnotation(AnnotationElementStudy.AnnotationOne.class);


        //获取指定类型所有注解(不包含继承),返回注解数组为AnnotationOne
        Annotation[] declaredAnnotationsByType = AnnotationElementStudy.Stu.class.getDeclaredAnnotationsByType(AnnotationElementStudy.AnnotationOne.class);


        //获取所有注解(不包含继承),返回注解数组为AnnotationOne、AnnotationTwo
        Annotation[] declaredAnnotations = AnnotationElementStudy.Stu.class.getDeclaredAnnotations();

        //返回当前类实例的父类注解类型(AnnotatedType),如果当前类实例是Object、interface、array type、primary type、void则返回null
        AnnotatedType annotatedSuperclass = Stu.class.getAnnotatedSuperclass(); //com.study.classStudy.ClassStudy$Person<com.study.classStudy.ClassStudy$Element>

        //返回当前类实例的实现接口的所有注解类型
        AnnotatedType[] annotatedInterfaces = Stu.class.getAnnotatedInterfaces(); //com.study.classStudy.ClassStudy$Drink<Integer>
    }


    public enum SCHOOL_TYPE {
        PRIMARY, MIDDLE;
    }

    public interface Eat {}

    public interface Drink<T> { }

    public static class Element {}

    @AnnotationThree
    @BaseAnnotation(base = 1)
    public static class Person<T> implements Eat {
        public Integer age;

        public Person() {
        }

        public Person(Integer age) {
            this.age = age;
        }

        public static class Head {
        }

        public Integer getAge() {
            return age;
        }

        public void setAge(Integer age) {
            this.age = age;
        }
    }

    @AnnotationOne
    @AnnotationTwo
    public static class Stu<Integer, Element> extends Person<Element> implements Drink<Integer> {
        public String stuName;

        public Object skill;

        public Stu() {
            class Skill {
            }
            skill = new Skill();
        }

        public Stu(String stuName) {
            this.stuName = stuName;
        }

        private Stu(Object skill) {
            this.skill = skill;
        }

        public static Object getHobby() {
            //内部本地类
            class Hobby {
            }
            return new Hobby();
        }

        public class Think {
        }

        public void setStuName(String stunName) {
            this.stuName = stuName;
        }

    }

    @Inherited  //指定该注解可以被继承
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface BaseAnnotation {
        int base() default 1;
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AnnotationOne {
        int one() default 10;
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AnnotationTwo {
        int two() default 10;
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AnnotationThree {
        int three() default 10;
    }
}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值