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;
}
}