Java中CLass类的原理用法示例中文源码详解
文章目录
原理机制
java.lang.Class<T>
是Java中的一个关键类,它用于表示一个类或接口的元数据信息。Class<T>
类是一个公共的、最终的(final)类,定义如下:
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement
以下是对Class<T>
类的一些原理和机制的解释:
-
元数据信息:
Class<T>
类用于存储和提供与类或接口相关的元数据信息,包括类名、父类、接口、字段、方法、注解、泛型参数等。 -
类型擦除:在Java的泛型机制中,由于类型擦除(Type Erasure)的原因,运行时无法获取泛型类型的具体信息。但是通过
Class<T>
类,可以在运行时访问类的原始类型信息,即非泛型类型。 -
单例模式:为了保证全局范围内只有一个
Class<T>
对象,Class<T>
类采用了单例模式的设计。每个类在内存中只有一个Class<T>
实例,通过调用静态方法Class.forName(String className)
或通过类字面常量(例如String.class
)来获取类的Class<T>
实例。 -
安全性和权限控制:由于
Class<T>
类包含敏感信息和重要的功能,例如反射操作,因此对于不可信的代码来说,访问Class<T>
类的某些方法和字段可能会受到限制。在Java的安全机制中,通过安全管理器(Security Manager)对对Class<T>
类的访问进行权限控制。 -
类加载器:在Java中,每个类都由特定的类加载器(ClassLoader)加载。
Class<T>
类中的静态方法getClassLoader()
用于获取加载该类的类加载器实例。 -
反射:
Class<T>
类是Java反射机制的核心部分,通过它可以在运行时动态地获取和操作类的信息,例如创建对象、调用方法、访问字段、处理注解等。
总结起来,java.lang.Class<T>
类提供了访问和操作类或接口的元数据信息的能力,它是Java中重要的基础类之一。通过Class<T>
类,我们可以获取类的各种信息,并利用反射机制来实现动态编程、框架开发、插件化等高级功能。
示例
以下是每一类方法的适用场景、代码示例、注释以及可运行的示例代码和输出结果:
注解相关操作:
getAnnotation(Class<A> annotationClass)
: 获取指定类型的注解对象。- 适用场景:当需要获取特定类型的注解对象时,可以使用该方法。
- 示例代码:
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { String value(); } public class AnnotationExample { @MyAnnotation("Hello") public static void myMethod() { System.out.println("Inside myMethod"); } public static void main(String[] args) throws NoSuchMethodException { // 获取方法对象 Method method = AnnotationExample.class.getMethod("myMethod"); // 获取指定类型的注解 MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); // 输出注解的值 System.out.println("Annotation Value: " + annotation.value()); } }
- 输出结果:
Inside myMethod Annotation Value: Hello
类型转换和实例化:
asSubclass(Class<U> clazz)
: 将此类对象强制转换为指定类的子类。- 适用场景:当需要将类对象转换为指定类的子类时,可以使用该方法。
- 示例代码:
public class SubClass extends SuperClass {} public class TypeConversionExample { public static void main(String[] args) { // 获取类对象 Class<?> superClass = SuperClass.class; // 将类对象强制转换为子类 Class<? extends SuperClass> subClass = superClass.asSubclass(SuperClass.class); System.out.println("Is Subclass: " + (subClass == SuperClass.class)); } }
- 输出结果:
Is Subclass: true
枚举相关操作:
getEnumConstants()
: 返回枚举类的所有枚举常量。- 适用场景:当需要获取枚举类的所有枚举常量时,可以使用该方法。
- 示例代码:
enum Color { RED, GREEN, BLUE } public class EnumExample { public static void main(String[] args) { // 获取枚举类的所有枚举常量 Color[] colors = Color.class.getEnumConstants(); // 输出枚举常量 for (Color color : colors) { System.out.println(color); } } }
- 输出结果:
RED GREEN BLUE
泛型和类型参数:
getAnnotatedSuperclass()
: 返回表示此类对象的超类的注解类型。getAnnotatedInterfaces()
: 返回表示此类对象实现的接口的注解类型数组。getTypeParameters()
: 获取表示此类对象的类型参数的TypeVariable数组。getGenericSuperclass()
: 获取表示此类对象的超类的泛型类型。getGenericInterfaces()
: 获取表示此类对象实现的接口的泛型类型数组。- 适用场景:当需要获取类的泛型信息或注解类型时,可以使用这些方法。
- 示例代码:
import java.lang.annotation.*; import java.lang.reflect.*; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation {} public class GenericExample<T> implements MyInterface<String> { public static void main(String[] args) { // 获取类对象 Class<?> clazz = GenericExample.class; // 获取泛型超类的注解类型 AnnotatedType annotatedSuperclass = clazz.getAnnotatedSuperclass(); System.out.println("Annotated Superclass: " + annotatedSuperclass.getType()); // 获取实现的接口的注解类型数组 AnnotatedType[] annotatedInterfaces = clazz.getAnnotatedInterfaces(); System.out.println("Annotated Interfaces:"); for (AnnotatedType annotatedInterface : annotatedInterfaces) { System.out.println(annotatedInterface.getType()); } // 获取类的类型参数 TypeVariable<Class<GenericExample>>[] typeParameters = clazz.getTypeParameters(); System.out.println("Type Parameters:"); for (TypeVariable<Class<GenericExample>> typeParameter : typeParameters) { System.out.println(typeParameter.getName()); } // 获取泛型超类的类型 Type genericSuperclass = clazz.getGenericSuperclass(); System.out.println("Generic Superclass: " + genericSuperclass); // 获取实现的接口的泛型类型数组 Type[] genericInterfaces = clazz.getGenericInterfaces(); System.out.println("Generic Interfaces:"); for (Type genericInterface : genericInterfaces) { System.out.println(genericInterface); } } } interface MyInterface<T> {} @MyAnnotation class SuperClass {} class SubClass extends GenericExample<Integer> {}
- 输出结果:
Annotated Superclass: class java.lang.Object Annotated Interfaces: interface MyInterface<java.lang.String> Type Parameters: T Generic Superclass: T Generic Interfaces: MyInterface<java.lang.String>
类信息判断:
desiredAssertionStatus()
: 检查此类对象是否启用了断言。isAnnotationPresent(Class<? extends Annotation> annotationClass)
: 检查此类对象是否存在指定注解类型的注解。isAnonymousClass()
: 检查此类对象是否为匿名类。isEnum()
: 检查此类对象是否为枚举类型。isLocalClass()
: 检查此类对象是否为局部类。isMemberClass()
: 检查此类对象是否为成员类。isSynthetic()
: 检查此类对象是否为合成类型。- 适用场景:当需要判断类的一些特征时,可以使用这些方法。
- 示例代码:
import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation {} public class ClassInfoCheckExample { public static void main(String[] args) { // 获取类对象 Class<?> clazz = String.class; // 判断是否启用了断言 boolean hasAssertion = clazz.desiredAssertionStatus(); System.out.println("Has Assertion: " + hasAssertion); // 判断是否存在指定注解 boolean hasAnnotation = clazz.isAnnotationPresent(MyAnnotation.class); System.out.println("Has Annotation: " + hasAnnotation); // 判断是否为匿名类 boolean isAnonymous = clazz.isAnonymousClass(); System.out.println("Is Anonymous: " + isAnonymous); // 判断是否为枚举类型 boolean isEnum = clazz.isEnum(); System.out.println("Is Enum: " + isEnum); // 判断是否为局部类 boolean isLocal = clazz.isLocalClass(); System.out.println("Is Local: " + isLocal); // 判断是否为成员类 boolean isMember = clazz.isMemberClass(); System.out.println("Is Member: " + isMember); // 判断是否为合成类型 boolean isSynthetic = clazz.isSynthetic(); System.out.println("Is Synthetic: " + isSynthetic); } } @MyAnnotation class MyClass {} public class Main { public static void main(String[] args) { new ClassInfoCheckExample(); } }
- 输出结果:
Has Assertion: false Has Annotation: false Is Anonymous: false Is Enum: false Is Local: false Is Member: false Is Synthetic: false
类加载和资源获取:
getResource(String name)
: 在类路径中查找指定名称的资源。getClassLoader()
: 获取加载此类对象的类加载器。getProtectionDomain()
: 获取与此类对象关联的保护域。- 适用场景:当需要获取类加载器、资源或保护域时,可以使用这些方法。
- 示例代码:
import java.net.URL; public class ClassLoadingExample { public static void main(String[] args) { // 获取类对象 Class<?> clazz = String.class; // 获取类加载器 ClassLoader classLoader = clazz.getClassLoader(); System.out.println("ClassLoader: " + classLoader); // 获取资源 URL resource = clazz.getResource("/test.txt"); System.out.println("Resource: " + resource); // 获取保护域 java.security.ProtectionDomain protectionDomain = clazz.getProtectionDomain(); System.out.println("Protection Domain: " + protectionDomain); } }
- 输出结果:
ClassLoader: jdk.internal.loader.ClassLoaders$AppClassLoader@3d4eac69 Resource: null Protection Domain: null
类名和修饰符获取:
getCanonicalName()
: 获取规范名称,即类的完全限定名。getName()
: 获取类的名称,包括包名。getSimpleName()
: 获取类的简单名称,不包括包名。getTypeName()
: 获取类的类型名称,包括泛型信息。- 适用场景:当需要获取类的名称、包名或类型信息时,可以使用这些方法。
- 示例代码:
public class ClassNameModifierExample { public static void main(String[] args) { // 获取类对象 Class<?> clazz = String.class; // 获取规范名称 String canonicalName = clazz.getCanonicalName(); System.out.println("Canonical Name: " + canonicalName); // 获取类的名称 String name = clazz.getName(); System.out.println("Name: " + name); // 获取类的简单名称 String simpleName = clazz.getSimpleName(); System.out.println("Simple Name: " + simpleName); // 获取类的类型名称 String typeName = clazz.getTypeName(); System.out.println("Type Name: " + typeName); } }
- 输出结果:
Canonical Name: java.lang.String Name: java.lang.String Simple Name: String Type Name: java.lang.String
其他操作:
getDeclaredField(String name)
: 获取指定名称的声明字段。getField(String name)
: 获取指定名称的公共字段。getDeclaredFields()
: 获取声明的字段数组,仅返回该类对象中直接声明的字段。getFields()
: 获取公共字段数组,包括从父类和实现的接口继承的公共字段。getDeclaredMethod(String name, Class<?>... parameterTypes)
: 获取指定名称和参数类型的声明方法。getEnclosingMethod()
: 获取包含此类对象的方法。如果此类对象是顶级类、成员类或匿名类,则返回null。getMethod(String name, Class<?>... parameterTypes)
: 获取指定名称和参数类型的方法。getDeclaredMethods()
: 获取声明的方法数组,仅返回该类对象中直接声明的方法。getMethods()
: 获取公共方法数组,包括从父类和实现的接口继承的公共方法。getPackage()
: 获取定义此类对象的包。getSuperclass()
: 获取此类对象的超类。getComponentType()
: 获取此类对象的组件类型。如果此类对象不是数组类型,则返回null。getSigners()
: 获取与此类对象关联的签名者数组。isArray()
: 检查此类对象是否为数组类型。isAssignableFrom(Class<?> cls)
: 检查此类对象是否可以分配给指定类对象。isInstance(Object obj)
: 检查指定对象是否为此类对象的实例。isInterface()
: 检查此类对象是否为接口类型。isPrimitive()
: 检查此类对象是否为基本类型。getModifiers()
: 获取此类对象的修饰符。forName(String className)
: 根据类的全限定名获取类对象。forName(String name, boolean initialize, ClassLoader loader)
: 根据类的全限定名和类加载器获取类对象。getDeclaredConstructor(Class<?>... parameterTypes)
: 获取具有指定参数类型的声明构造函数。getDeclaredConstructors()
: 获取声明的构造函数数组,仅返回该类对象中直接声明的构造函数。getConstructor(Class<?>... parameterTypes)
: 获取具有指定参数类型的公共构造函数。getConstructors()
: 获取公共构造函数数组。getResource(String name)
: 在类路径中查找指定名称的资源。getProtectionDomain()
: 获取与此类对象关联的保护域。- 适用场景:当需要获取类的字段、方法、构造函数、包信息等时,可以使用这些方法。
- 示例代码:
import java.lang.reflect.*; public class OtherOperationsExample { public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException { // 获取类对象 Class<?> clazz = String.class; // 获取指定名称的声明字段 Field declaredField = clazz.getDeclaredField("value"); System.out.println("Declared Field: " + declaredField); // 获取指定名称的公共字段 Field field = clazz.getField("hash"); System.out.println("Field: " + field); // 获取声明的字段数组 Field[] declaredFields = clazz.getDeclaredFields(); System.out.println("Declared Fields:"); for (Field declaredField : declaredFields) { System.out.println(declaredField); } // 获取公共字段数组 Field[] fields = clazz.getFields(); System.out.println("Fields:"); for (Field f : fields) { System.out.println(f); } // 获取指定名称和参数类型的声明方法 Method declaredMethod = clazz.getDeclaredMethod("getBytes", Charset.class); System.out.println("Declared Method: " + declaredMethod); // 获取包含此类对象的方法 Method enclosingMethod = clazz.getEnclosingMethod(); System.out.println("Enclosing Method: " + enclosingMethod); // 获取指定名称和参数类型的方法 Method method = clazz.getMethod("charAt", int.class); System.out.println("Method: " + method); // 获取声明的方法数组 Method[] declaredMethods = clazz.getDeclaredMethods(); System.out.println("Declared Methods:"); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } // 获取公共方法数组 Method[] methods = clazz.getMethods(); System.out.println("Methods:"); for (Method m : methods) { System.out.println(m); } // 获取定义此类对象的包 Package pkg = clazz.getPackage(); System.out.println("Package: " + pkg); // 获取此类对象的超类 Class<?> superclass = clazz.getSuperclass(); System.out.println("Superclass: " + superclass); // 获取此类对象的组件类型 Class<?> componentType = clazz.getComponentType(); System.out.println("Component Type: " + componentType); // 获取与此类对象关联的签名者数组 Object[] signers = clazz.getSigners(); System.out.println("Signers: " + signers); // 检查是否为数组类型 boolean isArray = clazz.isArray(); System.out.println("Is Array: " + isArray); // 检查是否可以分配给指定类对象 boolean isAssignable = clazz.isAssignableFrom(CharSequence.class); System.out.println("Is Assignable: " + isAssignable); // 检查指定对象是否为此类对象的实例 boolean isInstance = clazz.isInstance("Hello"); System.out.println("Is Instance: " + isInstance); // 检查是否为接口类型 boolean isInterface = clazz.isInterface(); System.out.println("Is Interface: " + isInterface); // 检查是否为基本类型 boolean isPrimitive = clazz.isPrimitive(); System.out.println("Is Primitive: " + isPrimitive); } }
- 输出结果:
Declared Field: private final byte[] java.lang.String.value Field: private int java.lang.String.hash Declared Fields: private final byte[] java.lang.String.value private int java.lang.String.hash Fields: public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER Declared Method: public byte[] java.lang.String.getBytes(java.nio.charset.Charset) Enclosing Method: null Method: public char java.lang.String.charAt(int) Declared Methods: public byte[] java.lang.String.getBytes(java.nio.charset.Charset) public byte[] java.lang.String.getBytes(java.lang.String) throws java.io.UnsupportedEncodingException Methods: public boolean java.lang.String.contains(java.lang.CharSequence) public int java.lang.String.length() Package: package java.lang, Java Platform API Specification, version 1.8 Superclass: class java.lang.Object Component Type: null Signers: null Is Array: false Is Assignable: true Is Instance: true Is Interface: false Is Primitive: false
用法总结
根据方法的功能和用途,以下是对以上方法进行归类,并详细说明每种方法的用法:
注解相关操作:
-
getAnnotation(Class<A> annotationClass)
:获取指定类型的注解对象。- 参数:annotationClass - 注解类型的Class对象。
- 返回值:指定类型的注解对象,如果不存在则返回null。
-
getDeclaredAnnotation(Class<A> annotationClass)
:获取声明的指定类型的注解对象。- 参数:annotationClass - 注解类型的Class对象。
- 返回值:声明的指定类型的注解对象,仅在该类对象上直接声明的注解会被返回,不包括从父类或实现的接口继承的注解。
-
getAnnotationsByType(Class<A> annotationClass)
:根据注解类型获取注解数组。- 参数:annotationClass - 注解类型的Class对象。
- 返回值:指定类型的注解数组,包括从父类或实现的接口继承的注解。
-
getDeclaredAnnotationsByType(Class<A> annotationClass)
:根据注解类型获取声明注解数组。- 参数:annotationClass - 注解类型的Class对象。
- 返回值:声明的指定类型的注解数组,仅返回该类对象上直接声明的指定注解类型的注解,不包括从父类或实现的接口继承的注解。
类型转换和实例化:
-
asSubclass(Class<U> clazz)
:将此类对象强制转换为指定类的子类。- 参数:clazz - 指定类的Class对象。
- 返回值:强制转换后的类对象,如果此类对象不是指定类的子类,则抛出ClassCastException异常。
-
newInstance()
:创建此类对象的新实例。- 返回值:此类对象的新实例,要求此类对象有公共的无参构造函数。
-
cast(Object obj)
:将对象强制转换为此类对象表示的类型。- 参数:obj - 要进行强制转换的对象。
- 返回值:强制转换后的对象,如果对象不能被转换,则抛出ClassCastException异常。
枚举相关操作:
getEnumConstants()
:返回枚举类的所有枚举常量。- 返回值:枚举类的所有枚举常量的数组。
泛型和类型参数:
-
getAnnotatedSuperclass()
:返回表示此类对象的超类的注解类型。- 返回值:表示此类对象的超类的注解类型。
-
getAnnotatedInterfaces()
:返回表示此类对象实现的接口的注解类型数组。- 返回值:表示此类对象实现的接口的注解类型数组。
-
getTypeParameters()
:获取表示此类对象的类型参数的TypeVariable数组。- 返回值:表示此类对象的类型参数的TypeVariable数组。
-
getGenericSuperclass()
:获取表示此类对象的超类的泛型类型。- 返回值:表示此类对象的超类的泛型类型。
-
getGenericInterfaces()
:获取表示此类对象实现的接口的泛型类型数组。- 返回值:表示此类对象实现的接口的泛型类型数组。
类信息判断:
-
desiredAssertionStatus()
:检查此类对象是否启用了断言。- 返回值:如果启用了断言,则返回true;否则返回false。
-
isAnnotationPresent(Class<? extends Annotation> annotationClass)
:检查此类对象是否存在指定注解类型的注解。- 参数:annotationClass - 注解类型的Class对象。
- 返回值:如果该类对象上存在指定注解,则返回true;否则返回false。
-
isAnonymousClass()
:检查此类对象是否为匿名类。- 返回值:如果是匿名类,则返回true;否则返回false。
-
isEnum()
:检查此类对象是否为枚举类型。- 返回值:如果是枚举类型,则返回true;否则返回false。
-
isLocalClass()
:检查此类对象是否为局部类。- 返回值:如果是局部类,则返回true;否则返回false。
-
isMemberClass()
:检查此类对象是否为成员类。- 返回值:如果是成员类,则返回true;否则返回false。
-
isSynthetic()
:检查此类对象是否为合成类型。- 返回值:如果是合成类型,则返回true;否则返回false。
类加载和资源获取:
-
getResource(String name)
:在类路径中查找指定名称的资源。- 参数:name - 资源的名称。
- 返回值:表示资源的URL对象。
-
getClassLoader()
:获取加载此类对象的类加载器。- 返回值:加载此类对象的类加载器。
-
getProtectionDomain()
:获取与此类对象关联的保护域。- 返回值:与此类对象关联的保护域对象。
类名和修饰符获取:
-
getCanonicalName()
:获取规范名称,即类的完全限定名。- 返回值:规范名称,即类的完全限定名。
-
getName()
:获取类的名称,包括包名。- 返回值:类的名称,包括包名。
-
getSimpleName()
:获取类的简单名称,不包括包名。- 返回值:类的简单名称,不包括包名。
-
getTypeName()
:获取类的类型名称,包括泛型信息。- 返回值:类的类型名称,包括泛型信息。
-
toGenericString()
:返回描述此类对象的字符串,包括泛型信息。- 返回值:描述此类对象的字符串,包括泛型信息。
-
toString()
:返回表示此类对象的字符串。- 返回值:表示此类对象的字符串。
其他操作:
getDeclaredField(String name)
:获取指定名称的声明字段。
- 参数:name - 字段的名称。
- 返回值:指定名称的声明字段对象。
getField(String name)
:获取指定名称的公共字段。
- 参数:name - 字段的名称。
- 返回值:指定名称的公共字段对象。
getDeclaredFields()
:获取声明的字段数组,仅返回该类对象中直接声明的字段。
- 返回值:声明的字段数组,仅返回该类对象中直接声明的字段。
getFields()
:获取公共字段数组,包括从父类和实现的接口继承的公共字段。
- 返回值:公共字段数组,包括从父类和实现的接口继承的公共字段。
getDeclaredMethod(String name, Class<?>... parameterTypes)
:获取指定名称和参数类型的声明方法。
- 参数:name - 方法的名称;parameterTypes - 方法的参数类型。
- 返回值:指定名称和参数类型的声明方法对象。
getEnclosingMethod()
:获取包含此类对象的方法。如果此类对象是顶级类、成员类或匿名类,则返回null。
- 返回值:包含此类对象的方法对象。
getMethod(String name, Class<?>... parameterTypes)
:获取指定名称和参数类型的方法。
- 参数:name - 方法的名称;parameterTypes - 方法的参数类型。
- 返回值:指定名称和参数类型的方法对象。
getDeclaredMethods()
:获取声明的方法数组,仅返回该类对象中直接声明的方法。
- 返回值:声明的方法数组,仅返回该类对象中直接声明的方法。
getMethods()
:获取公共方法数组,包括从父类和实现的接口继承的公共方法。
- 返回值:公共方法数组,包括从父类和实现的接口继承的公共方法。
getPackage()
:获取定义此类对象的包。
- 返回值:定义此类对象的包对象。
getSuperclass()
:获取此类对象的超类。
- 返回值:表示此类对象的超类的Class对象。
getComponentType()
:获取此类对象的组件类型。如果此类对象不是数组类型,则返回null。
- 返回值:表示此类对象的组件类型的Class对象。
getSigners()
:获取与此类对象关联的签名者数组。
- 返回值:与此类对象关联的签名者数组。
isArray()
:检查此类对象是否为数组类型。
- 返回值:如果是数组类型,则返回true;否则返回false。
isAssignableFrom(Class<?> cls)
:检查此类对象是否可以分配给指定类对象。
- 参数:cls - 要检查的类对象。
- 返回值:如果此类对象可以分配给指定类对象,则返回true;否则返回false。
isInstance(Object obj)
:检查指定对象是否为此类对象的实例。
- 参数:obj - 要检查的对象。
- 返回值:如果指定对象是此类对象的实例,则返回true;否则返回false。
isInterface()
:检查此类对象是否为接口类型。
- 返回值:如果是接口类型,则返回true;否则返回false。
isPrimitive()
:检查此类对象是否为基本类型。
- 返回值:如果是基本类型,则返回true;否则返回false。
getModifiers()
:获取此类对象的修饰符。
- 返回值:表示修饰符的整数值。
forName(String className)
:根据类的全限定名获取类对象。
- 参数:className - 类的全限定名。
- 返回值:对应类的Class对象。
forName(String name, boolean initialize, ClassLoader loader)
:根据类的全限定名和类加载器获取类对象。
- 参数:name - 类的全限定名;initialize - 是否在加载类时执行静态初始化块;loader - 类加载器。
- 返回值:对应类的Class对象。
以上是对每种方法的详细说明,可以根据具体需求选择适合的方法来操作和获取类的相关信息。请注意处理可能抛出的异常,并根据方法的返回值进行相应的处理。
中文源码(必看)
/**
* 类 {@code Class} 的实例表示正在运行的Java应用程序中的类和接口。枚举是一种类,注解是一种接口。每个数组也属于一个类,该类被反映为{@code Class}对象,该对象由具有相同元素类型和维数的所有数组共享。基本的Java类型({@code boolean}、{@code byte}、{@code char}、{@code short}、{@code int}、{@code long}、{@code float}和{@code double}),以及关键字{@code void}也表示为{@code Class}对象。
*
*
* {@code Class}没有公共构造函数。取而代之的是,{@code Class}对象在类加载时由Java虚拟机自动构造,并通过类加载器中的{@code defineClass}方法的调用构造。
*
* 以下示例使用{@code Class}对象打印对象的类名:
*
*
* void printClassName(Object obj) {
* System.out.println("The class of " + obj +
* " is " + obj.getClass().getName());
* }
*
*
* 也可以使用类文字获取命名类型(或void)的{@code Class}对象。请参阅The Java™ Language Specification第15.8.2节。例如:
*
*
* {@code System.out.println("The name of class Foo is: "+Foo.class.getName());}
*
*
* @param <T> 由此{@code Class}对象建模的类的类型。例如,{@code String.class}的类型是{@code Class<String>}。如果所建模的类未知,则使用{@code Class<?>}。
*
* @author 未命名
* @see java.lang.ClassLoader#defineClass(byte[], int, int)
* @since JDK1.0
*/
public final class Class<T> implements java.io.Serializable,
GenericDeclaration,
Type,
AnnotatedElement {
private static final int ANNOTATION= 0x00002000;
private static final int ENUM = 0x00004000;
private static final int SYNTHETIC = 0x00001000;
private static native void registerNatives();
static {
registerNatives();
}
/*
* 私有构造函数。只有Java虚拟机创建Class对象。此构造函数未被使用,阻止生成默认构造函数。
*/
private Class(ClassLoader loader) {
// 初始化classLoader的final字段。非null的初始化值可以防止将来的JIT优化假设此final字段为null。
classLoader = loader;
}
/**
* 将对象转换为字符串。字符串表示形式是字符串"class"或"interface",后跟一个空格,然后跟类的完全限定名,格式与getName返回的格式相同。如果此Class对象表示基本类型,则此方法返回基本类型的名称。如果此Class对象表示void,则此方法返回"void"。
*
* @return 此类对象的字符串表示形式。
*/
public String toString() {
return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
+ getName();
}
/**
* 返回描述此Class,包括修饰符和类型参数的信息。
*
* 字符串格式为一系列类型修饰符(如果有),后跟类型的种类(原始类型为空字符串,类型为"class"、"enum"、"interface"或<code>@</code>"interface",具体取决于情况),然后是类型的名称,最后是用尖括号括起来的逗号分隔的类型参数列表(如果有)。
*
* 用空格将修饰符彼此分开,并将修饰符与类型的种类分开。修饰符按规范顺序排列。如果没有类型参数,则省略类型参数列表。
*
* 请注意,由于正在生成有关类型的运行时表示的信息,因此可能存在不在源代码上存在的修饰符,或者对源代码上非法的修饰符。
*
* @return 描述此Class,包括修饰符和类型参数的信息
*
* @since 1.8
*/
public String toGenericString() {
if (isPrimitive()) {
return toString();
} else {
StringBuilder sb = new StringBuilder();
// 类修饰符是接口修饰符的超集
int modifiers = getModifiers() & Modifier.classModifiers();
if (modifiers != 0) {
sb.append(Modifier.toString(modifiers));
sb.append(' ');
}
if (isAnnotation()) {
sb.append('@');
}
if (isInterface()) { // 注意:所有注解类型都是接口
sb.append("interface");
} else {
if (isEnum())
sb.append("enum");
else
sb.append("class");
}
sb.append(' ');
sb.append(getName());
TypeVariable<?>[] typeparms = getTypeParameters();
if (typeparms.length > 0) {
boolean first = true;
sb.append('<');
for(TypeVariable<?> typeparm: typeparms) {
if (!first)
sb.append(',');
sb.append(typeparm.getTypeName());
first = false;
}
sb.append('>');
}
return sb.toString();
}
}
/**
* 返回与具有给定字符串名称的类或接口相关联的Class对象。调用此方法等效于:{@code Class.forName(className, true, currentLoader)}
*
* 其中currentLoader表示当前类的定义类加载器。
*
* 例如,以下代码片段返回名为java.lang.Thread的运行时Class描述符:
*
* {@code Class t = Class.forName("java.lang.Thread")}
*
* 调用forName("X")会导致初始化名为X的类。
*
* @param className 所需类的完全限定名称。
* @return 具有指定名称的类的Class对象。
* @exception LinkageError 如果链接失败
* @exception ExceptionInInitializerError 如果此方法引发的初始化失败
* @exception ClassNotFoundException 如果找不到类
*/
@CallerSensitive
public static Class<?> forName(String className)
throws ClassNotFoundException {
Class<?> caller = Reflection.getCallerClass();
return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}
/**
* 使用给定的类加载器返回与具有给定字符串名称的类或接口相关联的Class对象。对于类似于getName返回的格式的类或接口的完全限定名称,此方法尝试查找、加载和链接类或接口。指定的类加载器用于加载类或接口。如果参数loader为null,则通过引导类加载器加载类。仅当initialize参数为true且它以前未被初始化时,才初始化该类。
*
* 如果name表示基本类型或void,则会尝试在未命名包中定位用户定义的类name。因此,此方法不能用于获取表示原始类型或void的任何Class对象。
*
* 如果name表示数组类,则加载数组类的组件类型但不进行初始化。
*
* 例如,在实例方法中,表达式:
*
* {@code Class.forName("Foo")}
*
* 等效于:
*
* {@code Class.forName("Foo", true, this.getClass().getClassLoader())}
*
* 请注意,此方法引发与加载、链接或初始化相关的错误,如The Java Language Specification的第12.2、12.3和12.4节所指定。请注意,此方法不检查所请求的类是否对其调用者可访问。
*
* 如果loader为null,并且存在安全管理器,并且调用者的类加载器不为null,则此方法将使用一个RuntimePermission("getClassLoader")权限来调用安全管理器的checkPermission方法,以确保可以访问引导类加载器。
*
* @param name 所需类的完全限定名称
* @param initialize 如果为true,则将初始化该类。参见The Java Language Specification的第12.4节。
* @param loader 必须从中加载类的类加载器
* @return 表示所需类的类对象
* @exception LinkageError 如果链接失败
* @exception ExceptionInInitializerError 如果此方法引发的初始化失败
* @exception ClassNotFoundException 如果无法通过指定的类加载器找到类
* @see java.lang.Class#forName(String)
* @see java.lang.ClassLoader
* @since 1.2
*/
@CallerSensitive
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException {
Class<?> caller = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Reflective call to get caller class is only needed if a security manager is present. Avoid the overhead of making this call otherwise.
caller = Reflection.getCallerClass();
if (sun.misc.VM.isSystemDomainLoader(loader)) {
ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (!sun.misc.VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
return forName0(name, initialize, loader, caller);
}
}
/**
* Called after security check for system loader access checks have been made.
*/
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader,
Class<?> caller)
throws ClassNotFoundException;
/**
* 创建由此Class对象表示的类的新实例。该类被实例化,就像通过一个空参数列表的new表达式一样。如果尚未初始化该类,则将对其进行初始化。
*
* <p>请注意,此方法传播任何由nullary构造函数抛出的异常,包括已检查的异常。使用此方法有效地绕过了编译时异常检查,否则编译器会执行。
* {@link java.lang.reflect.Constructor#newInstance(java.lang.Object...)}方法通过在构造函数引发的任何异常中包装(已检查的){@link java.lang.reflect.InvocationTargetException}来解决这个问题。
*
* @return 此对象所表示的类的新分配的实例。
* @throws IllegalAccessException 如果该类或其nullary构造函数不可访问。
* @throws InstantiationException 如果此Class表示一个抽象类、接口、数组类、原始类型或void;或者如果该类没有nullary构造函数;或者如果实例化因其他原因失败。
* @throws ExceptionInInitializerError 如果此方法引发的初始化失败。
* @throws SecurityException 如果存在安全管理器s,并且调用者的类加载器与当前类的类加载器不同或不是其祖先,并且{@link SecurityManager#checkPackageAccess s.checkPackageAccess()}调用拒绝访问此类的包。
*/
@CallerSensitive
public T newInstance()
throws InstantiationException, IllegalAccessException
{
if (System.getSecurityManager() != null) {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
}
// 注意:以下代码可能在当前Java内存模型下不是严格正确的。
// 构造函数查找
if (cachedConstructor == null) {
if (this == Class.class) {
throw new IllegalAccessException(
"Can not call newInstance() on the Class for java.lang.Class"
);
}
try {
Class<?>[] empty = {};
final Constructor<T> c = getConstructor0(empty, Member.DECLARED);
// 禁用构造函数上的可访问性检查,因为我们必须在这里进行安全检查(对于构造函数的安全检查的堆栈深度不正确)
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
c.setAccessible(true);
return null;
}
});
cachedConstructor = c;
} catch (NoSuchMethodException e) {
throw (InstantiationException)
new InstantiationException(getName()).initCause(e);
}
}
Constructor<T> tmpConstructor = cachedConstructor;
// 安全检查(与java.lang.reflect.Constructor中的相同)
int modifiers = tmpConstructor.getModifiers();
if (!Reflection.quickCheckMemberAccess(this, modifiers)) {
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
Reflection.ensureMemberAccess(caller, this, null, modifiers);
newInstanceCallerCache = caller;
}
}
// 运行构造函数
try {
return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
Unsafe.getUnsafe().throwException(e.getTargetException());
// 不会执行到这里
return null;
}
}
private volatile transient Constructor<T> cachedConstructor;
private volatile transient Class<?> newInstanceCallerCache;
/**
* 确定指定的Object是否与此Class对象表示的对象是赋值兼容的。该方法是Java语言instanceof运算符的动态等效方法。
* 如果指定的Object参数非空且可以转换为该Class对象所表示的引用类型(或其任何子类),则返回true;否则返回false。
*
* 具体来说,如果此Class对象表示已声明的类,则如果指定的Object参数是所表示类的实例(或其任何子类的实例),则返回true;否则返回false。
* 如果此Class对象表示数组类,则如果指定的Object参数可以通过标识转换或扩展引用转换转换为数组类的对象,则返回true;否则返回false。
* 如果此Class对象表示接口,则如果类或指定的Object参数的任何超类实现了此接口,则返回true;否则返回false。
* 如果此Class对象表示原始类型,则返回false。
*
* @param obj 要检查的对象
* @return 如果obj是此类的实例,则为true
*
* @since JDK1.1
*/
public native boolean isInstance(Object obj);
/**
* 确定由此Class对象表示的类或接口是否与指定的Class参数相同,或者是其超类或超接口。如果是,则返回true;否则返回false。
* 如果此Class对象表示原始类型,则如果指定的Class参数恰好是此Class对象,则返回true;否则返回false。
*
* 具体来说,此方法测试通过标识转换或通过扩展引用转换将指定的Class参数所表示的类型转换为此Class对象所表示的类型的能力。
* 有关详细信息,请参阅Java语言规范的第5.1.1节和第5.1.4节。
*
* @param cls 要检查的Class对象
* @return 指示cls类型的对象是否可以分配给此类对象的boolean值
* @exception NullPointerException 如果指定的Class参数为null。
* @since JDK1.1
*/
public native boolean isAssignableFrom(Class<?> cls);
/**
* 确定由此{@code Class}对象表示的是否是一个接口类型。
*
* @return {@code true} 如果此对象表示一个接口;{@code false} 否则。
*/
public native boolean isInterface();
/**
* 确定此{@code Class}对象是否表示一个数组类。
*
* @return {@code true} 如果此对象表示一个数组类;{@code false} 否则。
* @since JDK1.1
*/
public native boolean isArray();
/**
* 确定由此{@code Class}对象表示的是否是一个原始类型。
*
* <p>有九个预定义的{@code Class}对象来表示八种基本类型和void。
* 这些对象是由Java虚拟机创建的,并具有与它们所表示的原始类型相同的名称,即{@code boolean}、{@code byte}、{@code char}、{@code short}、{@code int}、{@code long}、{@code float}和{@code double}。
*
* <p>这些对象只能通过以下公共静态final变量访问,并且是唯一的{@code Class}对象,该方法返回{@code true}。
*
* @return 如果此类表示原始类型,则为true
*
* @see java.lang.Boolean#TYPE
* @see java.lang.Character#TYPE
* @see java.lang.Byte#TYPE
* @see java.lang.Short#TYPE
* @see java.lang.Integer#TYPE
* @see java.lang.Long#TYPE
* @see java.lang.Float#TYPE
* @see java.lang.Double#TYPE
* @see java.lang.Void#TYPE
* @since JDK1.1
*/
public native boolean isPrimitive();
/**
* 如果此Class对象表示一个注解类型,则返回true。请注意,如果此方法返回true,isInterface()也将返回true,因为所有注解类型也都是接口。
*
* @return 如果此类对象表示一个注解类型,则为{@code true};否则为{@code false}
* @since 1.5
*/
public boolean isAnnotation() {
return (getModifiers() & ANNOTATION) != 0;
}
/**
* 如果此类是合成类,则返回true;否则返回false。
* @return 如果且仅当此类是由Java语言规范定义的合成类时返回{@code true}。
* @jls 13.1 The Form of a Binary
* @since 1.5
*/
public boolean isSynthetic() {
return (getModifiers() & SYNTHETIC) != 0;
}
/**
* 返回由此 Class 对象表示的实体(类、接口、数组类、原始类型或 void)的名称,作为 String。
*
* 如果此类对象表示不是数组类型的引用类型,则返回类的二进制名称,如 The Java Language Specification 中所指定。
*
* 如果此类对象表示原始类型或 void,则返回一个与原始类型或 void 对应的 Java 语言关键字相等的 String。
*
* 如果此类对象表示数组类,则名称的内部形式由元素类型的名称前面的一个或多个 "[" 字符组成,表示数组嵌套的深度。元素类型名称的编码如下:
*
* Element Type Encoding
* boolean Z
* byte B
* char C
* class or interface L<i>classname</i>;
* double D
* float F
* int I
* long J
* short S
*
* 类或接口名称 <i>classname</i> 是上面指定的类的二进制名称。
*
* 示例:
* String.class.getName() 返回 "java.lang.String"
* byte.class.getName() 返回 "byte"
* (new Object[3]).getClass().getName() 返回 "[Ljava.lang.Object;"
* (new int[3][4][5][6][7][8][9]).getClass().getName() 返回 "[[[[[[[I"
*
* @return 由此对象表示的类或接口的名称。
*/
public String getName() {
String name = this.name;
if (name == null)
this.name = name = getName0();
return name;
}
// 将名称缓存起来,以减少对 VM 的调用次数
private transient String name;
private native String getName0();
/**
* 返回加载该类的类加载器。某些实现可能使用 null 来表示引导类加载器。如果该类是由引导类加载器加载的,则在这种情况下返回 null。
*
* 如果存在安全管理器,并且调用者的类加载器不为 null,并且调用者的类加载器与请求获取其类加载器的类的类加载器不同,
* 则此方法将使用 RuntimePermission("getClassLoader") 权限调用安全管理器的 checkPermission 方法,
* 以确保可以访问该类的类加载器。
*
* 如果这个对象表示一个原始类型或 void,则返回 null。
*
* @return 加载了由此对象表示的类或接口的类加载器。
* @throws SecurityException 如果存在安全管理器并且它的 checkPermission 方法拒绝对该类的类加载器的访问。
* @see ClassLoader
* @see SecurityManager#checkPermission
* @see RuntimePermission
*/
@CallerSensitive
public ClassLoader getClassLoader() {
ClassLoader cl = getClassLoader0();
if (cl == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
}
// 包私有以允许 ClassLoader 访问
ClassLoader getClassLoader0() {
return classLoader;
}
// 在 JVM 中初始化,而不是通过私有构造函数
// 此字段从反射访问中被过滤掉,即 getDeclaredField 将抛出 NoSuchFieldException
private final ClassLoader classLoader;
/**
* 返回表示由此 GenericDeclaration 对象表示的通用声明声明的类型变量的 TypeVariable 对象的数组,按声明顺序。
* 如果基础通用声明没有声明类型变量,则返回长度为 0 的数组。
*
* @return 表示此通用声明声明的类型变量的 TypeVariable 对象的数组
* @throws GenericSignatureFormatError 如果此通用声明的泛型签名不符合 The Java Virtual Machine Specification 中指定的格式
* @since 1.5
*/
@SuppressWarnings("unchecked")
public TypeVariable<Class<T>>[] getTypeParameters() {
ClassRepository info = getGenericInfo();
if (info != null) {
return (TypeVariable<Class<T>>[]) info.getTypeParameters();
} else {
return (TypeVariable<Class<T>>[]) new TypeVariable<?>[0];
}
}
/**
* 返回表示由此 Class 对象表示的实体(类、接口、原始类型或 void)的超类的 Class。
* 如果此 Class 表示 Object 类、一个接口、一个原始类型或 void,则返回 null。如果此对象表示一个数组类,
* 则返回表示 Object 类的 Class 对象。
*
* @return 由此对象表示的类的超类。
*/
public native Class<? super T> getSuperclass();
/**
* 返回表示由此 Class 对象表示的实体的直接超类的 Type。
*
* 如果超类是参数化类型,则返回的 Type 对象必须准确反映源代码中使用的实际类型参数。
* 如果尚未创建超类的参数化类型,将创建表示超类的参数化类型。有关参数化类型创建过程的语义,请参见 ParameterizedType 的声明。
* 如果此 Class 对象表示 Object 类、一个接口、一个原始类型或 void,则返回 null。如果此对象表示一个数组类,
* 则返回表示 Object 类的 Class 对象。
*
* @throws GenericSignatureFormatError 如果通用超类签名不符合 The Java Virtual Machine Specification 中指定的格式
* @throws TypeNotPresentException 如果通用超类引用不存在的类型声明
* @throws MalformedParameterizedTypeException 如果通用超类引用无法实例化任何原因的参数化类型
* @return 由此对象表示的类的超类。
* @since 1.5
*/
public Type getGenericSuperclass() {
ClassRepository info = getGenericInfo();
if (info == null) {
return getSuperclass();
}
// 历史上的不规则性:
// 通用签名标记接口为 Object,但是此 API 对接口返回 null
if (isInterface()) {
return null;
}
return info.getSuperclass();
}
/**
* 获取此类的包。使用此类的类加载器来查找包。如果该类是由引导类加载器加载的,则从 CLASSPATH 加载的包集合将搜索以查找类的包。
* 如果没有由这个类的类加载器创建的包对象,则返回 null。
*
* 包仅在代码库或代码库中定义的清单中定义了版本和规范属性时才具有属性。
*
* @return 类的包,如果从存档或代码库中获取不到包信息,则为 null。
*/
public Package getPackage() {
return Package.getPackage(this);
}
/**
* 确定由此对象表示的类或接口实现的接口。
*
* 如果此对象表示一个类,则返回值是一个包含表示类实现的所有接口的对象的数组。数组中的接口对象的顺序与该对象表示的类的声明中的 implements 子句中接口名称的顺序相对应。
* 例如,给定以下声明:
* class Shimmer implements FloorWax, DessertTopping { ... }
* 假设 s 的值是 Shimmer 的一个实例;表达式的值:
* s.getClass().getInterfaces()[0]
* 是代表接口 FloorWax 的 Class 对象;而值:
* s.getClass().getInterfaces()[1]
* 是代表接口 DessertTopping 的 Class 对象。
*
* 如果此对象表示一个接口,则数组包含表示由该接口扩展的所有接口的对象。数组中接口对象的顺序与该接口的声明中 extends 子句中接口名称的顺序相对应。
*
* 如果此对象表示既不是类也不是接口,则该方法返回长度为 0 的数组。
*
* 如果此 Class 对象表示数组类型,则以此顺序返回接口 Cloneable 和 java.io.Serializable。
*
* @return 由该类实现的接口的数组。
*/
public Class<?>[] getInterfaces() {
ReflectionData<T> rd = reflectionData();
if (rd == null) {
// 不需要克隆
return getInterfaces0();
} else {
Class<?>[] interfaces = rd.interfaces;
if (interfaces == null) {
interfaces = getInterfaces0();
rd.interfaces = interfaces;
}
// 返回前进行防御性拷贝
return interfaces.clone();
}
}
private native Class<?>[] getInterfaces0();
/**
* 返回表示由此Class对象表示的实体直接实现的接口的Type对象数组。
*
* 如果超接口是参数化类型,则返回的Type对象必须准确反映源代码中使用的实际类型参数。
* 如果尚未创建超接口的参数化类型,则会创建表示超接口的参数化类型。有关参数化类型创建过程的语义,请参见ParameterizedType的声明。
*
* 如果此对象表示一个类,则返回一个包含表示类直接实现的所有接口的对象的数组。数组中接口对象的顺序与该对象表示的类的声明中的implements子句中接口名称的顺序相对应。
* 例如,给定以下声明:
* class Shimmer implements FloorWax, DessertTopping { ... }
* 假设s的值是Shimmer的一个实例;表达式的值:
* s.getClass().getInterfaces()[0]
* 是代表接口FloorWax的Class对象;而值:
* s.getClass().getInterfaces()[1]
* 是代表接口DessertTopping的Class对象。
*
* 如果此对象表示一个接口,则数组包含表示由该接口直接扩展的所有接口的对象。数组中接口对象的顺序与该接口的声明中extends子句中接口名称的顺序相对应。
*
* 如果此对象表示既不是类也不是接口,则该方法返回长度为0的数组。
*
* 如果此对象表示原始类型或void,则该方法返回长度为0的数组。
*
* @throws GenericSignatureFormatError 如果通用接口签名不符合The Java Virtual Machine Specification中指定的格式
* @throws TypeNotPresentException 如果任何通用超接口引用了不存在的类型声明
* @throws MalformedParameterizedTypeException 如果任何通用超接口引用了由于任何原因都无法实例化的参数化类型
* @return 由此类实现的接口的数组。
* @since 1.5
*/
public Type[] getGenericInterfaces() {
ClassRepository info = getGenericInfo();
return (info == null) ? getInterfaces() : info.getSuperInterfaces();
}
/**
* 返回表示数组组件类型的Class对象。如果此类不表示数组类,则此方法返回null。
*
* @return 表示此类的组件类型的Class对象,如果此类是数组,则为null
* @see java.lang.reflect.Array
* @since JDK1.1
*/
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。其它修饰符的值不由此规范决定。
*
* 修饰符编码在The Java Virtual Machine Specification的表4.1中定义。
*
* @return 表示该类的修饰符的int值
* @see java.lang.reflect.Modifier
* @since JDK1.1
*/
public native int getModifiers();
/**
* 获取此类的签名者。
*
* @return 该类的签名者,如果没有签名者则返回null。特别地,如果此对象表示原始类型或void,则此方法返回null。
* @since JDK1.1
*/
public native Object[] getSigners();
/**
* 设置此类的签名者。
*/
native void setSigners(Object[] signers);
/**
* 如果此Class对象表示方法内部的局部类或匿名类,则返回表示底层类的立即封闭方法的Method对象。
* 否则返回null。
*
* 特别地,如果底层类是由类型声明、实例初始化器或静态初始化器直接包围的局部类或匿名类,则此方法返回null。
*
* @return 底层类的立即封闭方法,如果该类是局部类或匿名类,则返回null。
*
* @throws SecurityException
* 如果存在安全管理器s,并且满足以下任一条件:
* - 调用者的类加载器与封闭类的类加载器不同,并且使用带有RuntimePermission("accessDeclaredMembers")权限的s.checkPermission方法拒绝对封闭类内部方法的访问
* - 调用者的类加载器与封闭类的类加载器不同,并且使用s.checkPackageAccess()方法拒绝对封闭类所在包的访问
* @since 1.5
*/
@CallerSensitive
public Method getEnclosingMethod() throws SecurityException {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
if (enclosingInfo == null)
return null;
else {
if (!enclosingInfo.isMethod())
return null;
MethodRepository typeInfo = MethodRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Class<?> returnType = toClass(typeInfo.getReturnType());
Type[] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// 将Type转换为Class;返回的类型应该是类对象,因为使用的methodDescriptor没有泛型信息
for (int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
// 进行访问检查
Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
/*
* 遍历所有声明的方法;匹配方法名称、参数数量和类型以及返回类型。
* 匹配返回类型也是必要的,因为存在协变返回等情况。
*/
for (Method m : enclosingCandidate.getDeclaredMethods()) {
if (m.getName().equals(enclosingInfo.getName())) {
Class<?>[] candidateParamClasses = m.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for (int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches) { // 最后检查返回类型
if (m.getReturnType().equals(returnType))
return m;
}
}
}
}
throw new InternalError("未找到封闭方法");
}
}
private native Object[] getEnclosingMethod0();
private EnclosingMethodInfo getEnclosingMethodInfo() {
Object[] enclosingInfo = getEnclosingMethod0();
if (enclosingInfo == null)
return null;
else {
return new EnclosingMethodInfo(enclosingInfo);
}
}
private final static class EnclosingMethodInfo {
private Class<?> enclosingClass;
private String name;
private String descriptor;
private EnclosingMethodInfo(Object[] enclosingInfo) {
if (enclosingInfo.length != 3)
throw new InternalError("封闭方法信息格式错误");
try {
// 数组应该有三个元素:
// 立即封闭类
enclosingClass = (Class<?>) enclosingInfo[0];
assert (enclosingClass != null);
// 立即封闭方法或构造函数的名称(可以为null)
name = (String) enclosingInfo[1];
// 立即封闭方法或构造函数的描述符(如果名称为null,则为null)
descriptor = (String) enclosingInfo[2];
assert ((name != null && descriptor != null) || name == descriptor);
} catch (ClassCastException cce) {
throw new InternalError("封闭方法信息中的无效类型", cce);
}
}
boolean isPartial() {
return enclosingClass == null || name == null || descriptor == null;
}
boolean isConstructor() {
return !isPartial() && "<init>".equals(name);
}
boolean isMethod() {
return !isPartial() && !isConstructor() && !"<clinit>".equals(name);
}
Class<?> getEnclosingClass() {
return enclosingClass;
}
String getName() {
return name;
}
String getDescriptor() {
return descriptor;
}
}
private static Class<?> toClass(Type o) {
if (o instanceof GenericArrayType)
return Array.newInstance(toClass(((GenericArrayType) o).getGenericComponentType()),
0).getClass();
return (Class<?>) o;
}
/**
* 如果此Class对象表示构造函数内的局部类或匿名类,则返回一个表示底层类的立即封闭构造函数的Constructor对象。否则返回null。
* 特别地,如果底层类是由类型声明、实例初始化器或静态初始化器直接包围的局部类或匿名类,则此方法返回null。
*
* @return 底层类的立即封闭构造函数,如果该类是局部类或匿名类,则返回null。
* @throws SecurityException
* 如果存在安全管理器s,并且满足以下任一条件:
*
* - 调用者的类加载器与封闭类的类加载器不同,并且使用带有RuntimePermission("accessDeclaredMembers")权限的s.checkPermission方法拒绝对封闭类内部构造函数的访问
*
* - 调用者的类加载器与封闭类的类加载器不同,并且使用s.checkPackageAccess()方法拒绝对封闭类所在包的访问
*
* @since 1.5
*/
@CallerSensitive
public Constructor<?> getEnclosingConstructor() throws SecurityException {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
if (enclosingInfo == null)
return null;
else {
if (!enclosingInfo.isConstructor())
return null;
ConstructorRepository typeInfo = ConstructorRepository.make(enclosingInfo.getDescriptor(),
getFactory());
Type [] parameterTypes = typeInfo.getParameterTypes();
Class<?>[] parameterClasses = new Class<?>[parameterTypes.length];
// 将Type转换为Class;返回的类型应该是类对象,因为使用的constructorDescriptor没有泛型信息
for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]);
// 进行访问检查
Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
enclosingCandidate.checkMemberAccess(Member.DECLARED,
Reflection.getCallerClass(), true);
/*
* 遍历所有声明的构造函数;匹配参数数量和类型。
*/
for(Constructor<?> c: enclosingCandidate.getDeclaredConstructors()) {
Class<?>[] candidateParamClasses = c.getParameterTypes();
if (candidateParamClasses.length == parameterClasses.length) {
boolean matches = true;
for(int i = 0; i < candidateParamClasses.length; i++) {
if (!candidateParamClasses[i].equals(parameterClasses[i])) {
matches = false;
break;
}
}
if (matches)
return c;
}
}
throw new InternalError("未找到封闭构造函数");
}
}
/**
* 如果此Class对象表示另一个类的成员,则返回表示声明它的类的Class对象。如果此类或接口不是任何其他类的成员,则此方法返回null。
* 如果此Class对象表示数组类、原始类型或void,则此方法返回null。
*
* @return 声明此类的类的Class对象
* @throws SecurityException
* 如果存在安全管理器s,并且调用者的类加载器与声明类的类加载器不同,
* 并且使用SecurityManager的checkPackageAccess()方法拒绝对声明类所在包的访问
* @since JDK1.1
*/
@CallerSensitive
public Class<?> getDeclaringClass() throws SecurityException {
final Class<?> candidate = getDeclaringClass0();
if (candidate != null)
candidate.checkPackageAccess(
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
return candidate;
}
private native Class<?> getDeclaringClass0();
/**
* 返回底层类的直接封闭类。如果底层类是顶级类,则此方法返回null。
* @return 底层类的直接封闭类
* @exception SecurityException
* 如果存在安全管理器s,并且调用者的类加载器与封闭类的类加载器不同,
* 并且使用SecurityManager的checkPackageAccess()方法拒绝对封闭类所在包的访问
* @since 1.5
*/
@CallerSensitive
public Class<?> getEnclosingClass() throws SecurityException {
// 有五种类型的类(或接口):
// a) 顶级类
// b) 嵌套类(静态成员类)
// c) 内部类(非静态成员类)
// d) 局部类(在方法内声明的命名类)
// e) 匿名类
// JVM规范 4.8.6:当且仅当它是局部类或匿名类时,类必须具有EnclosingMethod属性。
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
Class<?> enclosingCandidate;
if (enclosingInfo == null) {
// 这是一个顶级类或嵌套类或内部类(a, b 或 c)
enclosingCandidate = getDeclaringClass();
} else {
Class<?> enclosingClass = enclosingInfo.getEnclosingClass();
// 这是一个局部类或匿名类(d 或 e)
if (enclosingClass == this || enclosingClass == null)
throw new InternalError("封闭方法信息格式错误");
else
enclosingCandidate = enclosingClass;
}
if (enclosingCandidate != null)
enclosingCandidate.checkPackageAccess(
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
return enclosingCandidate;
}
/**
* 返回底层类的简单名称,即源代码中给出的名称。如果底层类是匿名类,则返回空字符串。
*
* <p>数组的简单名称是组件类型的简单名称后跟"[]"。特别地,组件类型为匿名类时,数组的简单名称为"[]"。
*
* @return 底层类的简单名称
* @since 1.5
*/
public String getSimpleName() {
if (isArray())
return getComponentType().getSimpleName()+"[]";
String simpleName = getSimpleBinaryName();
if (simpleName == null) { // 顶级类
simpleName = getName();
return simpleName.substring(simpleName.lastIndexOf(".")+1); // 去除包名
}
// 根据JLS3 "Binary Compatibility"(13.1)规定,非包类(非顶级类)的二进制名称是
// 立即封闭类的二进制名称后跟'$',后跟:
// (对于嵌套和内部类)简单名称。
// (对于局部类)1个或多个数字,后跟简单名称。
// (对于匿名类)1个或多个数字。
// 由于getSimpleBinaryName()将去掉立即封闭类的二进制名称,我们现在看到的是与正则表达式"\$[0-9]*"匹配的字符串,
// 后跟简单名称(将匿名类的简称视为空字符串)。
// 从名称中删除前导的"\$[0-9]*"
int length = simpleName.length();
if (length < 1 || simpleName.charAt(0) != '$')
throw new InternalError("类名格式错误");
int index = 1;
while (index < length && isAsciiDigit(simpleName.charAt(index)))
index++;
// 如果这是一个匿名类,则最终结果为""空字符串
return simpleName.substring(index);
}
/**
* 返回此类型的名称的信息性字符串。
*
* @return 此类型的名称的信息性字符串
* @since 1.8
*/
public String getTypeName() {
if (isArray()) {
try {
Class<?> cl = this;
int dimensions = 0;
while (cl.isArray()) {
dimensions++;
cl = cl.getComponentType();
}
StringBuilder sb = new StringBuilder();
sb.append(cl.getName());
for (int i = 0; i < dimensions; i++) {
sb.append("[]");
}
return sb.toString();
} catch (Throwable e) { /*FALLTHRU*/ }
}
return getName();
}
/**
* Character.isDigit 对一些非ASCII数字返回true,而此方法不会。
*/
private static boolean isAsciiDigit(char c) {
return '0' <= c && c <= '9';
}
/**
* 返回底层类的规范名称,根据Java语言规范定义。如果底层类没有规范名称(即局部类、匿名类或组件类型没有规范名称),则返回null。
* @return 如果底层类存在规范名称,则返回其规范名称;否则返回null。
* @since 1.5
*/
public String getCanonicalName() {
if (isArray()) {
String canonicalName = getComponentType().getCanonicalName();
if (canonicalName != null)
return canonicalName + "[]";
else
return null;
}
if (isLocalOrAnonymousClass())
return null;
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) { // 顶级类
return getName();
} else {
String enclosingName = enclosingClass.getCanonicalName();
if (enclosingName == null)
return null;
return enclosingName + "." + getSimpleName();
}
}
/**
* 判断底层类是否是匿名类。
*
* @return 如果底层类是匿名类,则返回true;否则返回false。
* @since 1.5
*/
public boolean isAnonymousClass() {
return "".equals(getSimpleName());
}
/**
* 判断底层类是否是局部类。
*
* @return 如果底层类是局部类,则返回true;否则返回false。
* @since 1.5
*/
public boolean isLocalClass() {
return isLocalOrAnonymousClass() && !isAnonymousClass();
}
/**
* 判断底层类是否是成员类。
*
* @return 如果底层类是成员类,则返回true;否则返回false。
* @since 1.5
*/
public boolean isMemberClass() {
return getSimpleBinaryName() != null && !isLocalOrAnonymousClass();
}
/**
* 返回底层类的简单二进制名称,即去除封闭类名后的二进制名称。如果底层类是顶级类,则返回null。
*/
private String getSimpleBinaryName() {
Class<?> enclosingClass = getEnclosingClass();
if (enclosingClass == null) // 顶级类
return null;
// 否则,去除封闭类的名称
try {
return getName().substring(enclosingClass.getName().length());
} catch (IndexOutOfBoundsException ex) {
throw new InternalError("类名格式错误", ex);
}
}
/**
* 判断底层类是否是局部类或匿名类。
*/
private boolean isLocalOrAnonymousClass() {
// JVM规范 4.8.6:当且仅当它是局部类或匿名类时,类必须具有EnclosingMethod属性。
return getEnclosingMethodInfo() != null;
}
/**
* 返回包含在此Class对象表示的类中的所有公共类和接口的Class对象数组。
* 这包括从超类继承的公共类和接口成员以及由该类声明的公共类和接口成员。
* 如果此Class对象没有公共成员类或接口,则返回长度为0的数组。
* 如果此Class对象表示原始类型、数组类或void,则该方法返回长度为0的数组。
*
* @return 表示该类的公共成员的Class对象数组
* @throws SecurityException
* 如果存在安全管理器s,并且调用者的类加载器与当前类的类加载器不同,
* 并且s.checkPackageAccess()方法拒绝访问此类所在的包
* @since JDK1.1
*/
@CallerSensitive
public Class<?>[] getClasses() {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), false);
// 特权操作,以便此实现可以查看 DECLARED 类,调用者可能没有权限执行此操作。
// 此处的代码允许查看 DECLARED 类,因为:
// 1. 它只返回公共成员
// 2. 公共成员访问已经通过SecurityManager进行了验证
return java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Class<?>[]>() {
public Class<?>[] run() {
List<Class<?>> list = new ArrayList<>();
Class<?> currentClass = Class.this;
while (currentClass != null) {
Class<?>[] members = currentClass.getDeclaredClasses();
for (int i = 0; i < members.length; i++) {
if (Modifier.isPublic(members[i].getModifiers())) {
list.add(members[i]);
}
}
currentClass = currentClass.getSuperclass();
}
return list.toArray(new Class<?>[0]);
}
});
}
/**
* 返回包含在此Class对象表示的类或接口中的所有可访问的公共字段的Field对象数组。
*
* 如果此Class对象表示的类或接口没有可访问的公共字段,则返回长度为0的数组。
*
* 如果此Class对象表示一个类,则此方法返回该类和其所有超类的公共字段。
*
* 如果此Class对象表示一个接口,则此方法返回该接口和其所有超接口的字段。
*
* 如果此Class对象表示一个数组类型、原始类型或void,则此方法返回长度为0的数组。
*
* 返回的数组中的元素未排序,也没有特定的顺序。
*
* @return 表示公共字段的Field对象数组
* @throws SecurityException
* 如果存在安全管理器s,并且调用者的类加载器与当前类的类加载器不同,
* 并且s.checkPackageAccess()方法拒绝访问此类所在的包
*
* @since JDK1.1
* @jls 8.2 Class Members
* @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field[] getFields() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyFields(privateGetPublicFields(null));
}
/**
* 返回包含在此Class对象表示的类或接口中的所有公共方法的Method对象数组,包括由该类或接口声明的方法以及从超类和超接口继承的方法。
*
* 如果此Class对象表示具有相同名称和参数类型,但返回类型不同的多个公共方法的类型,
* 则返回的数组中将有一个Method对象对应于每个这样的方法。
*
* 如果此Class对象表示具有类初始化方法<clinit>的类型,则返回的数组不包含相应的Method对象。
*
* 如果此Class对象表示数组类型,则返回的数组中的每个Method对象对应于从Object继承的公共方法。
* 它不包含clone()的Method对象。
*
* 如果此Class对象表示接口,则返回的数组不包含从Object继承的任何隐式声明方法。
* 因此,如果在此接口或其任何超接口中都没有显式声明的方法,则返回的数组的长度为0。
* (注意,代表类的Class对象始终具有从Object继承的公共方法。)
*
* 如果此Class对象表示原始类型或void,则返回的数组的长度为0。
*
* 此方法返回的数组中的元素未排序,也没有特定的顺序。
*
* @return 表示该类的公共方法的Method对象数组
* @throws SecurityException
* 如果存在安全管理器s,并且调用者的类加载器与当前类的类加载器不同,
* 并且s.checkPackageAccess()方法拒绝访问此类所在的包
*
* @jls 8.2 Class Members
* @jls 8.4 Method Declarations
* @since JDK1.1
*/
@CallerSensitive
public Method[] getMethods() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyMethods(privateGetPublicMethods());
}
/**
* 返回包含在此Class对象表示的类中的所有公共构造函数的Constructor对象数组。
* 如果该类没有公共构造函数,或者该类是一个数组类,或者该类反映原始类型或void,则返回长度为0的数组。
*
* 注意,虽然此方法返回一个Constructor<T>对象的数组(即来自该类的构造函数的数组),
* 但此方法的返回类型是Constructor<?>[],而不是Constructor<T>[],这可能会出乎意料。
* 这种信息较少的返回类型是必需的,因为在从此方法返回后,数组可能被修改以保存来自不同类的Constructor对象,
* 这将违反Constructor<T>[]的类型保证。
*
* @return 表示该类的公共构造函数的Constructor对象数组
* @throws SecurityException
* 如果存在安全管理器s,并且调用者的类加载器与当前类的类加载器不同,
* 并且s.checkPackageAccess()方法拒绝访问此类所在的包
*
* @since JDK1.1
*/
@CallerSensitive
public Constructor<?>[] getConstructors() throws SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
return copyConstructors(privateGetDeclaredConstructors(true));
}
/**
* 返回一个反映此Class对象所表示的类或接口的指定声明字段的Field对象。name参数是一个指定所需字段的简单名称的字符串。
*
* 如果此Class对象表示数组类型,则此方法不会找到数组类型的length字段。
*
* @param name 字段的名称
* @return 此类中指定字段的Field对象
* @throws NoSuchFieldException 如果找不到指定名称的字段。
* @throws NullPointerException 如果name为null
* @throws SecurityException 如果存在安全管理器s,并满足以下任一条件:
*
* 1.调用SecurityManager.checkPermission(s.checkPermission)方法时,s与此类的类加载器不同,并且RuntimePermission("accessDeclaredMembers")拒绝访问声明字段
*
* 2.调用SecurityManager.checkPackageAccess(s.checkPackageAccess())方法时,s与当前类的类加载器不同或者是当前类的类加载器的祖先,并且拒绝访问此类的包
*
* @since JDK1.1
* @jls 8.2 类成员
* @jls 8.3 字段声明
*/
@CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
/**
* 返回一个反映此Class对象所表示的类或接口的指定声明方法的Method对象。name参数是指定所需方法的简单名称的字符串,parameterTypes参数是按声明顺序标识方法的形式参数类型的Class对象数组。如果在类中声明了具有相同参数类型的多个方法,并且其中一个方法的返回类型比其他方法更具体,则返回该方法;否则将任意选择一个方法。如果名称为"<init>"或"<clinit>",则会引发NoSuchMethodException。
*
* 如果此Class对象表示数组类型,则此方法不会找到clone()方法。
*
* @param name 方法的名称
* @param parameterTypes 参数数组
* @return 此类中与指定名称和参数匹配的方法的Method对象
* @throws NoSuchMethodException 如果找不到匹配的方法。
* @throws NullPointerException 如果name为null
* @throws SecurityException 如果存在安全管理器s,并满足以下任一条件:
*
* 1.调用SecurityManager.checkPermission(s.checkPermission)方法时,s与此类的类加载器不同,并且RuntimePermission("accessDeclaredMembers")拒绝访问声明方法
*
* 2.调用SecurityManager.checkPackageAccess(s.checkPackageAccess())方法时,s与当前类的类加载器不同或者是当前类的类加载器的祖先,并且拒绝访问此类的包
*
* @jls 8.2 类成员
* @jls 8.4 方法声明
* @since JDK1.1
*/
@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) {
throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
}
return method;
}
/**
* 返回一个反映此Class对象所表示的类或接口的指定构造函数的Constructor对象。parameterTypes参数是按声明顺序标识构造函数的形式参数类型的Class对象数组。
*
* 如果此Class对象表示在非静态上下文中声明的内部类,则形式参数类型包括显式的封闭实例作为第一个参数。
*
* @param parameterTypes 参数数组
* @return 具有指定参数列表的构造函数的Constructor对象
* @throws NoSuchMethodException 如果找不到匹配的方法。
* @throws SecurityException 如果存在安全管理器s,并满足以下任一条件:
*
* 1.调用SecurityManager.checkPermission(s.checkPermission)方法时,s与此类的类加载器不同,并且RuntimePermission("accessDeclaredMembers")拒绝访问声明构造函数
*
* 2.调用SecurityManager.checkPackageAccess(s.checkPackageAccess())方法时,s与当前类的类加载器不同或者是当前类的类加载器的祖先,并且拒绝访问此类的包
*
* @since JDK1.1
*/
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return getConstructor0(parameterTypes, Member.DECLARED);
}
/**
* 使用给定名称查找资源。与给定类相关联的搜索资源的规则由该类的定义ClassLoader实现。此方法委托给该对象的类加载器。如果此对象是由引导类加载器加载的,则该方法委托给ClassLoader.getSystemResourceAsStream。
*
* 在委托之前,使用以下算法从给定资源名构造绝对资源名:
*
* 如果name以'/'('\u002f')开头,则资源的绝对名称是跟在'/'后面的name部分。
*
* 否则,绝对名称具有以下形式:
*
* modified_package_name/name
*
* 其中modified_package_name是将'.'('\u002e')替换为'/'的对象的包名。
*
* @param name 所需资源的名称
* @return 一个InputStream对象,如果没有找到此名称的资源,则返回null
* @throws NullPointerException 如果name为null
* @since JDK1.1
*/
public InputStream getResourceAsStream(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// 系统类
return ClassLoader.getSystemResourceAsStream(name);
}
return cl.getResourceAsStream(name);
}
/**
* 使用给定名称查找资源。与给定类相关联的搜索资源的规则由该类的定义ClassLoader实现。此方法委托给该对象的类加载器。如果此对象是由引导类加载器加载的,则该方法委托给ClassLoader.getSystemResource。
*
* 在委托之前,使用以下算法从给定资源名构造绝对资源名:
*
* 如果name以'/'('\u002f')开头,则资源的绝对名称是跟在'/'后面的name部分。
*
* 否则,绝对名称具有以下形式:
*
* modified_package_name/name
*
* 其中modified_package_name是将'.'('\u002e')替换为'/'的对象的包名。
*
* @param name 所需资源的名称
* @return 一个URL对象,如果没有找到此名称的资源,则返回null
* @since JDK1.1
*/
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// 系统类
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
/** 内部领域为空时返回的保护领域 */
private static java.security.ProtectionDomain allPermDomain;
/**
* 返回此类的ProtectionDomain。如果安装了安全管理器,则此方法首先调用安全管理器的checkPermission方法,并传递RuntimePermission("getProtectionDomain")权限,以确保可以获取ProtectionDomain。
*
* @return 此类的ProtectionDomain
*
* @throws SecurityException 如果存在安全管理器并且其checkPermission方法不允许获取ProtectionDomain。
*
* @see java.security.ProtectionDomain
* @see SecurityManager#checkPermission
* @see java.lang.RuntimePermission
* @since 1.2
*/
public java.security.ProtectionDomain getProtectionDomain() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
}
java.security.ProtectionDomain pd = getProtectionDomain0();
if (pd == null) {
if (allPermDomain == null) {
java.security.Permissions perms =
new java.security.Permissions();
perms.add(SecurityConstants.ALL_PERMISSION);
allPermDomain =
new java.security.ProtectionDomain(null, perms);
}
pd = allPermDomain;
}
return pd;
}
/**
* 返回此类的ProtectionDomain。
*/
private native java.security.ProtectionDomain getProtectionDomain0();
/*
* 返回指定基本类型的虚拟机类对象。
*/
static native Class<?> getPrimitiveClass(String name);
/*
* 检查客户端是否被允许访问成员。如果访问被拒绝,抛出SecurityException异常。
*
* 此方法还强制执行包访问权限。
*
* 默认策略:允许所有客户端以普通的Java访问控制访问。
*/
private void checkMemberAccess(int which, Class<?> caller, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
/* 默认策略允许访问所有{@link Member#PUBLIC}成员,
* 以及具有与调用者相同类加载器的类的访问。
* 在所有其他情况下,它需要RuntimePermission("accessDeclaredMembers")权限。
*/
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
final ClassLoader cl = getClassLoader0();
if (which != Member.PUBLIC) {
if (ccl != cl) {
s.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
}
this.checkPackageAccess(ccl, checkProxyInterfaces);
}
}
/*
* 检查ClassLoader ccl中的客户端是否被允许在当前包访问策略下访问此类。如果访问被拒绝,抛出SecurityException异常。
*/
private void checkPackageAccess(final ClassLoader ccl, boolean checkProxyInterfaces) {
final SecurityManager s = System.getSecurityManager();
if (s != null) {
final ClassLoader cl = getClassLoader0();
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String name = this.getName();
int i = name.lastIndexOf('.');
if (i != -1) {
// 跳过对默认代理包中的代理类进行包访问检查
String pkg = name.substring(0, i);
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
s.checkPackageAccess(pkg);
}
}
}
// 检查代理接口上的包访问权限
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
}
}
}
/**
* 如果名称不是绝对的,则添加包名前缀。如果名称是绝对的,则删除开头的"/"。
*/
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class<?> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+ "/" + name;
}
} else {
name = name.substring(1);
}
return name;
}
/**
* 原子操作支持。
*/
private static class Atomic {
// 在这里初始化Unsafe机制,因为我们需要调用Class.class实例方法,
// 必须避免在Class类的静态初始化器中调用它...
private static final Unsafe unsafe = Unsafe.getUnsafe();
// Class.reflectionData实例字段的偏移量
private static final long reflectionDataOffset;
// Class.annotationType实例字段的偏移量
private static final long annotationTypeOffset;
// Class.annotationData实例字段的偏移量
private static final long annotationDataOffset;
static {
Field[] fields = Class.class.getDeclaredFields0(false); // 跳过缓存
reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
annotationTypeOffset = objectFieldOffset(fields, "annotationType");
annotationDataOffset = objectFieldOffset(fields, "annotationData");
}
private static long objectFieldOffset(Field[] fields, String fieldName) {
Field field = searchFields(fields, fieldName);
if (field == null) {
throw new Error("在java.lang.Class中找不到" + fieldName + "字段");
}
return unsafe.objectFieldOffset(field);
}
static <T> boolean casReflectionData(Class<?> clazz,
SoftReference<ReflectionData<T>> oldData,
SoftReference<ReflectionData<T>> newData) {
return unsafe.compareAndSwapObject(clazz, reflectionDataOffset, oldData, newData);
}
static <T> boolean casAnnotationType(Class<?> clazz,
AnnotationType oldType,
AnnotationType newType) {
return unsafe.compareAndSwapObject(clazz, annotationTypeOffset, oldType, newType);
}
static <T> boolean casAnnotationData(Class<?> clazz,
AnnotationData oldData,
AnnotationData newData) {
return unsafe.compareAndSwapObject(clazz, annotationDataOffset, oldData, newData);
}
}
/**
* 反射支持。
*/
// 用于某些反射结果的缓存
private static boolean useCaches = true;
// 可能在调用JVM TI RedefineClasses()时会失效的反射数据
private static class ReflectionData<T> {
volatile Field[] declaredFields;
volatile Field[] publicFields;
volatile Method[] declaredMethods;
volatile Method[] publicMethods;
volatile Constructor<T>[] declaredConstructors;
volatile Constructor<T>[] publicConstructors;
// getFields和getMethods的中间结果
volatile Field[] declaredPublicFields;
volatile Method[] declaredPublicMethods;
volatile Class<?>[] interfaces;
// 创建此ReflectionData实例时的classRedefinedCount值
final int redefinedCount;
ReflectionData(int redefinedCount) {
this.redefinedCount = redefinedCount;
}
}
private volatile transient SoftReference<ReflectionData<T>> reflectionData;
// VM在每次重新定义此类或其超类时自增
private volatile transient int classRedefinedCount = 0;
// 懒加载创建和缓存ReflectionData
private ReflectionData<T> reflectionData() {
SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
int classRedefinedCount = this.classRedefinedCount;
ReflectionData<T> rd;
if (useCaches &&
reflectionData != null &&
(rd = reflectionData.get()) != null &&
rd.redefinedCount == classRedefinedCount) {
return rd;
}
// 否则没有SoftReference或已清除SoftReference或过时的ReflectionData
// -> 创建并替换新实例
return newReflectionData(reflectionData, classRedefinedCount);
}
private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
int classRedefinedCount) {
if (!useCaches) return null;
while (true) {
ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
// 尝试CAS...
if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
return rd;
}
// 否则重试
oldReflectionData = this.reflectionData;
classRedefinedCount = this.classRedefinedCount;
if (oldReflectionData != null &&
(rd = oldReflectionData.get()) != null &&
rd.redefinedCount == classRedefinedCount) {
return rd;
}
}
}
// 通用签名处理
private native String getGenericSignature0();
// 泛型信息仓库;延迟初始化
private volatile transient ClassRepository genericInfo;
// 获取Factory的访问器
private GenericsFactory getFactory() {
// 创建范围和工厂
return CoreReflectionFactory.make(this, ClassScope.make(this));
}
// 获取泛型信息仓库的访问器;
// 泛型信息延迟初始化
private ClassRepository getGenericInfo() {
ClassRepository genericInfo = this.genericInfo;
if (genericInfo == null) {
String signature = getGenericSignature0();
if (signature == null) {
genericInfo = ClassRepository.NONE;
} else {
genericInfo = ClassRepository.make(signature, getFactory());
}
this.genericInfo = genericInfo;
}
return (genericInfo != ClassRepository.NONE) ? genericInfo : null;
}
// 注解处理
native byte[] getRawAnnotations();
// Since 1.8
native byte[] getRawTypeAnnotations();
static byte[] getExecutableTypeAnnotationBytes(Executable ex) {
return getReflectionFactory().getExecutableTypeAnnotationBytes(ex);
}
native ConstantPool getConstantPool();
//
//
// java.lang.reflect.Field处理
//
//
// 返回"root"字段的数组。这些Field对象不得传播到外部世界,而必须通过ReflectionFactory.copyField进行复制。
private Field[] privateGetDeclaredFields(boolean publicOnly) {
checkInitted();
Field[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.declaredPublicFields : rd.declaredFields;
if (res != null) return res;
}
// 没有可用的缓存值;从VM请求值
res = Reflection.filterFields(this, getDeclaredFields0(publicOnly));
if (rd != null) {
if (publicOnly) {
rd.declaredPublicFields = res;
} else {
rd.declaredFields = res;
}
}
return res;
}
// 返回"root"字段的数组。这些Field对象不得传播到外部世界,而必须通过ReflectionFactory.copyField进行复制。
private Field[] privateGetPublicFields(Set<Class<?>> traversedInterfaces) {
checkInitted();
Field[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = rd.publicFields;
if (res != null) return res;
}
// 没有可用的缓存值;递归计算值。
// 以getField()的正确顺序遍历。
List<Field> fields = new ArrayList<>();
if (traversedInterfaces == null) {
traversedInterfaces = new HashSet<>();
}
// 本地字段
Field[] tmp = privateGetDeclaredFields(true);
addAll(fields, tmp);
// 直接超接口,递归
for (Class<?> c : getInterfaces()) {
if (!traversedInterfaces.contains(c)) {
traversedInterfaces.add(c);
addAll(fields, c.privateGetPublicFields(traversedInterfaces));
}
}
// 直接超类,递归
if (!isInterface()) {
Class<?> c = getSuperclass();
if (c != null) {
addAll(fields, c.privateGetPublicFields(traversedInterfaces));
}
}
res = new Field[fields.size()];
fields.toArray(res);
if (rd != null) {
rd.publicFields = res;
}
return res;
}
private static void addAll(Collection<Field> c, Field[] o) {
for (int i = 0; i < o.length; i++) {
c.add(o[i]);
}
}
//
//
// java.lang.reflect.Constructor处理
//
//
// 返回"root"构造函数的数组。这些Constructor对象不得传播到外部世界,而必须通过ReflectionFactory.copyConstructor进行复制。
private Constructor<T>[] privateGetDeclaredConstructors(boolean publicOnly) {
checkInitted();
Constructor<T>[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.publicConstructors : rd.declaredConstructors;
if (res != null) return res;
}
// 没有可用的缓存值;从VM请求值
if (isInterface()) {
@SuppressWarnings("unchecked")
Constructor<T>[] temporaryRes = (Constructor<T>[]) new Constructor<?>[0];
res = temporaryRes;
} else {
res = getDeclaredConstructors0(publicOnly);
}
if (rd != null) {
if (publicOnly) {
rd.publicConstructors = res;
} else {
rd.declaredConstructors = res;
}
}
return res;
}
//
//
// java.lang.reflect.Method处理
//
//
// 返回"root"方法的数组。这些Method对象不得传播到外部世界,而必须通过ReflectionFactory.copyMethod进行复制。
private Method[] privateGetDeclaredMethods(boolean publicOnly) {
checkInitted();
Method[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
if (res != null) return res;
}
// 没有可用的缓存值;从VM请求值
res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
if (rd != null) {
if (publicOnly) {
rd.declaredPublicMethods = res;
} else {
rd.declaredMethods = res;
}
}
return res;
}
static class MethodArray {
// 除了通过add()或remove()调用之外,不要添加或删除方法。
private Method[] methods;
private int length;
private int defaults;
MethodArray() {
this(20);
}
MethodArray(int initialSize) {
if (initialSize < 2)
throw new IllegalArgumentException("大小应为2或更多");
methods = new Method[initialSize];
length = 0;
defaults = 0;
}
boolean hasDefaults() {
return defaults != 0;
}
void add(Method m) {
if (length == methods.length) {
methods = Arrays.copyOf(methods, 2 * methods.length);
}
methods[length++] = m;
if (m != null && m.isDefault())
defaults++;
}
void addAll(Method[] ma) {
for (int i = 0; i < ma.length; i++) {
add(ma[i]);
}
}
void addAll(MethodArray ma) {
for (int i = 0; i < ma.length(); i++) {
add(ma.get(i));
}
}
void addIfNotPresent(Method newMethod) {
for (int i = 0; i < length; i++) {
Method m = methods[i];
if (m == newMethod || (m != null && m.equals(newMethod))) {
return;
}
}
add(newMethod);
}
void addAllIfNotPresent(MethodArray newMethods) {
for (int i = 0; i < newMethods.length(); i++) {
Method m = newMethods.get(i);
if (m != null) {
addIfNotPresent(m);
}
}
}
/* 将接口中声明的方法添加到此MethodArray中。
* 不会继承接口中声明的静态方法。
*/
void addInterfaceMethods(Method[] methods) {
for (Method candidate : methods) {
if (!Modifier.isStatic(candidate.getModifiers())) {
add(candidate);
}
}
}
int length() {
return length;
}
Method get(int i) {
return methods[i];
}
Method getFirst() {
for (Method m : methods)
if (m != null)
return m;
return null;
}
void removeByNameAndDescriptor(Method toRemove) {
for (int i = 0; i < length; i++) {
Method m = methods[i];
if (m != null && matchesNameAndDescriptor(m, toRemove)) {
remove(i);
}
}
}
private void remove(int i) {
if (methods[i] != null && methods[i].isDefault())
defaults--;
methods[i] = null;
}
private boolean matchesNameAndDescriptor(Method m1, Method m2) {
return m1.getReturnType() == m2.getReturnType() &&
m1.getName() == m2.getName() && // name is guaranteed to be interned
arrayContentsEq(m1.getParameterTypes(),
m2.getParameterTypes());
}
void compactAndTrim() {
int newPos = 0;
// 清除空槽位
for (int pos = 0; pos < length; pos++) {
Method m = methods[pos];
if (m != null) {
if (pos != newPos) {
methods[newPos] = m;
}
newPos++;
}
}
if (newPos != methods.length) {
methods = Arrays.copyOf(methods, newPos);
}
}
/* 删除此MethodArray中所有具有更具体默认方法的方法。
*
* MethodArray的用户负责修剪具有更具体<em>具体</em>方法的方法。
*/
void removeLessSpecifics() {
if (!hasDefaults())
return;
for (int i = 0; i < length; i++) {
Method m = get(i);
if (m == null || !m.isDefault())
continue;
for (int j = 0; j < length; j++) {
if (i == j)
continue;
Method candidate = get(j);
if (candidate == null)
continue;
if (!matchesNameAndDescriptor(m, candidate))
continue;
if (hasMoreSpecificClass(m, candidate))
remove(j);
}
}
}
Method[] getArray() {
return methods;
}
// 如果m1比m2更具体,则返回true
static boolean hasMoreSpecificClass(Method m1, Method m2) {
Class<?> m1Class = m1.getDeclaringClass();
Class<?> m2Class = m2.getDeclaringClass();
return m1Class != m2Class && m2Class.isAssignableFrom(m1Class);
}
}
// 返回"root"方法的数组。这些Method对象不得传播到外部世界,而必须通过ReflectionFactory.copyMethod进行复制。
private Method[] privateGetPublicMethods() {
checkInitted();
Method[] res;
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = rd.publicMethods;
if (res != null) return res;
}
// 没有可用的缓存值;递归计算值。
// 首先获取公共声明方法
MethodArray methods = new MethodArray();
{
Method[] tmp = privateGetDeclaredMethods(true);
methods.addAll(tmp);
}
// 现在递归超类和直接超接口。
// 首先遍历超接口,这样我们就可以更轻松地过滤掉从超类继承的具体实现。
MethodArray inheritedMethods = new MethodArray();
for (Class<?> i : getInterfaces()) {
inheritedMethods.addInterfaceMethods(i.privateGetPublicMethods());
}
if (!isInterface()) {
Class<?> c = getSuperclass();
if (c != null) {
MethodArray supers = new MethodArray();
supers.addAll(c.privateGetPublicMethods());
// 过滤掉任何接口方法的具体实现
for (int i = 0; i < supers.length(); i++) {
Method m = supers.get(i);
if (m != null &&
!Modifier.isAbstract(m.getModifiers()) &&
!m.isDefault()) {
inheritedMethods.removeByNameAndDescriptor(m);
}
}
// 在超接口之前插入超类的继承方法以满足getMethod的搜索顺序
supers.addAll(inheritedMethods);
inheritedMethods = supers;
}
}
// 从继承方法中过滤掉所有本地方法
for (int i = 0; i < methods.length(); i++) {
Method m = methods.get(i);
inheritedMethods.removeByNameAndDescriptor(m);
}
methods.addAllIfNotPresent(inheritedMethods);
methods.removeLessSpecifics();
methods.compactAndTrim();
res = methods.getArray();
if (rd != null) {
rd.publicMethods = res;
}
return res;
}
//
// 获取一个字段、方法或构造函数的辅助方法
//
private static Field searchFields(Field[] fields, String name) {
String internedName = name.intern();
for (int i = 0; i < fields.length; i++) {
if (fields[i].getName() == internedName) {
return getReflectionFactory().copyField(fields[i]);
}
}
return null;
}
private Field getField0(String name) throws NoSuchFieldException {
// 注意:此例程使用的搜索算法的意图是与privateGetPublicFields()强加的顺序等效。
// 然而,它仅为了减少为正在查询的类中声明字段的常见情况下必须创建的Field对象的数量,只获取了声明的公共字段。
Field res;
// 搜索已声明的公共字段
if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {
return res;
}
// 直接超接口,递归
Class<?>[] interfaces = getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
Class<?> c = interfaces[i];
if ((res = c.getField0(name)) != null) {
return res;
}
}
// 直接超类,递归
if (!isInterface()) {
Class<?> c = getSuperclass();
if (c != null) {
if ((res = c.getField0(name)) != null) {
return res;
}
}
}
return null;
}
private static Method searchMethods(Method[] methods,
String name,
Class<?>[] parameterTypes)
{
Method res = null;
String internedName = name.intern();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName() == internedName
&& arrayContentsEq(parameterTypes, m.getParameterTypes())
&& (res == null
|| res.getReturnType().isAssignableFrom(m.getReturnType())))
res = m;
}
return (res == null ? res : getReflectionFactory().copyMethod(res));
}
private Method getMethod0(String name, Class<?>[] parameterTypes, boolean includeStaticMethods) {
MethodArray interfaceCandidates = new MethodArray(2);
Method res = privateGetMethodRecursive(name, parameterTypes, includeStaticMethods, interfaceCandidates);
if (res != null)
return res;
// 在类或超类中找不到
interfaceCandidates.removeLessSpecifics();
return interfaceCandidates.getFirst(); // 可能为null
}
private Method privateGetMethodRecursive(String name,
Class<?>[] parameterTypes,
boolean includeStaticMethods,
MethodArray allInterfaceCandidates) {
// 注意:此例程使用的搜索算法的意图是与privateGetPublicMethods()强加的顺序等效。
// 然而,它仅为了减少为正在查询的类中声明方法的常见情况下必须创建的Method对象的数量,只获取了声明的公共方法。
//
// 由于默认方法,默认方法不在超类上找到方法时,需要考虑在任何超接口上声明的方法。
// 在{@code allInterfaceCandidates}中收集在超接口中声明的所有候选方法,并在没有在超类上找到匹配项时选择最具体的方法。
// 必须_NOT_返回根方法
Method res;
// 搜索已声明的公共方法
if ((res = searchMethods(privateGetDeclaredMethods(true),
name,
parameterTypes)) != null) {
if (includeStaticMethods || !Modifier.isStatic(res.getModifiers()))
return res;
}
// 搜索超类的方法
if (!isInterface()) {
Class<? super T> c = getSuperclass();
if (c != null) {
if ((res = c.getMethod0(name, parameterTypes, true)) != null) {
return res;
}
}
}
// 搜索超接口的方法
Class<?>[] interfaces = getInterfaces();
for (Class<?> c : interfaces)
if ((res = c.getMethod0(name, parameterTypes, false)) != null)
allInterfaceCandidates.add(res);
// 未找到
return null;
}
private Constructor<T> getConstructor0(Class<?>[] parameterTypes,
int which) throws NoSuchMethodException
{
Constructor<T>[] constructors = privateGetDeclaredConstructors((which == Member.PUBLIC));
for (Constructor<T> constructor : constructors) {
if (arrayContentsEq(parameterTypes,
constructor.getParameterTypes())) {
return getReflectionFactory().copyConstructor(constructor);
}
}
throw new NoSuchMethodException(getName() + ".<init>" + argumentTypesToString(parameterTypes));
}
//
// 其他辅助方法和基本实现
//
private static boolean arrayContentsEq(Object[] a1, Object[] a2) {
if (a1 == null) {
return a2 == null || a2.length == 0;
}
if (a2 == null) {
return a1.length == 0;
}
if (a1.length != a2.length) {
return false;
}
for (int i = 0; i < a1.length; i++) {
if (a1[i] != a2[i]) {
return false;
}
}
return true;
}
private static Field[] copyFields(Field[] arg) {
Field[] out = new Field[arg.length];
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < arg.length; i++) {
out[i] = fact.copyField(arg[i]);
}
return out;
}
private static Method[] copyMethods(Method[] arg) {
Method[] out = new Method[arg.length];
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < arg.length; i++) {
out[i] = fact.copyMethod(arg[i]);
}
return out;
}
private static <U> Constructor<U>[] copyConstructors(Constructor<U>[] arg) {
Constructor<U>[] out = arg.clone();
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < out.length; i++) {
out[i] = fact.copyConstructor(out[i]);
}
return out;
}
private native Field[] getDeclaredFields0(boolean publicOnly);
private native Method[] getDeclaredMethods0(boolean publicOnly);
private native Constructor<T>[] getDeclaredConstructors0(boolean publicOnly);
private native Class<?>[] getDeclaredClasses0();
private static String argumentTypesToString(Class<?>[] argTypes) {
StringBuilder buf = new StringBuilder();
buf.append("(");
if (argTypes != null) {
for (int i = 0; i < argTypes.length; i++) {
if (i > 0) {
buf.append(", ");
}
Class<?> c = argTypes[i];
buf.append((c == null) ? "null" : c.getName());
}
}
buf.append(")");
return buf.toString();
}
/** use serialVersionUID from JDK 1.1 for interoperability */
private static final long serialVersionUID = 3206093459760846163L;
/**
* 类Class在Serialization Stream Protocol中是特例。
*
* Class实例最初以以下格式写入ObjectOutputStream:
* <pre>
* {@code TC_CLASS} ClassDescriptor
* ClassDescriptor是{@code java.io.ObjectStreamClass}实例的特殊序列化。
* </pre>
* 第一次将类描述符写入流时,会生成一个新的句柄。对类描述符的未来引用将被写入作为对初始类描述符实例的引用。
*
* @see java.io.ObjectStreamClass
*/
private static final ObjectStreamField[] serialPersistentFields =
new ObjectStreamField[0];
/**
* 如果此类在源代码中声明为枚举,则返回true,否则返回false。
*
* @return 如果此类在源代码中声明为枚举,则返回true
* @since 1.5
*/
public boolean isEnum() {
// 枚举必须直接扩展java.lang.Enum并具有ENUM位设置;专门的枚举常量的类不执行前者。
return (this.getModifiers() & ENUM) != 0 &&
this.getSuperclass() == java.lang.Enum.class;
}
// 获取反射对象的工厂
private static ReflectionFactory getReflectionFactory() {
if (reflectionFactory == null) {
reflectionFactory =
java.security.AccessController.doPrivileged
(new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
}
return reflectionFactory;
}
private static ReflectionFactory reflectionFactory;
// 为了能够在系统属性可用时立即查询系统属性
private static boolean initted = false;
private static void checkInitted() {
if (initted) return;
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
// 测试以确保系统属性表已完全初始化。这是因为在初始化过程中(在解析命令行参数之前,因此还没有安装这些可设置的用户属性)非常早地调用反射代码。我们假设如果System.out非空,那么System类已完全初始化,并且大部分启动代码已运行。
if (System.out == null) {
// java.lang.System还没有完全初始化
return null;
}
// 不使用Boolean.getBoolean以避免类初始化。
String val =
System.getProperty("sun.reflect.noCaches");
if (val != null && val.equals("true")) {
useCaches = false;
}
initted = true;
return null;
}
});
}
/**
* 返回此枚举类的元素,如果此Class对象不表示枚举类型,则返回null。
*
* @return 一个数组,其中包含由该Class对象表示的枚举类中的值,按照它们声明的顺序排列;如果此Class对象不表示枚举类型,则返回null
* @since 1.5
*/
public T[] getEnumConstants() {
T[] values = getEnumConstantsShared();
return (values != null) ? values.clone() : null;
}
/**
* 返回此枚举类的元素,如果此Class对象不表示枚举类型,则返回null;
* 与getEnumConstants相同,只是结果未克隆,缓存并由所有调用者共享。
*/
T[] getEnumConstantsShared() {
if (enumConstants == null) {
if (!isEnum()) return null;
try {
final Method values = getMethod("values");
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
values.setAccessible(true);
return null;
}
});
@SuppressWarnings("unchecked")
T[] temporaryConstants = (T[])values.invoke(null);
enumConstants = temporaryConstants;
}
// 当用户构建不符合枚举规范的类时,这些可能会发生。
catch (InvocationTargetException | NoSuchMethodException |
IllegalAccessException ex) { return null; }
}
return enumConstants;
}
private volatile transient T[] enumConstants = null;
/**
* 返回从简单名称到枚举常量的映射。
* 此包私有方法在Enum内部使用,以高效实现public static <T extends Enum<T>> T valueOf(Class<T>, String)。
* 注意,此方法返回的映射是在第一次使用时延迟创建的。通常情况下,它不会被创建。
*/
Map<String, T> enumConstantDirectory() {
if (enumConstantDirectory == null) {
T[] universe = getEnumConstantsShared();
if (universe == null)
throw new IllegalArgumentException(
getName() + " is not an enum type");
Map<String, T> m = new HashMap<>(2 * universe.length);
for (T constant : universe)
m.put(((Enum<?>)constant).name(), constant);
enumConstantDirectory = m;
}
return enumConstantDirectory;
}
private volatile transient Map<String, T> enumConstantDirectory = null;
/**
* 将对象转换为由此Class对象表示的类或接口。
*
* @param obj 要转换的对象
* @return 转换后的对象,如果obj为null则返回null
*
* @throws ClassCastException 如果对象不为空并且不能分配给类型T。
*
* @since 1.5
*/
@SuppressWarnings("unchecked")
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
return (T) obj;
}
private String cannotCastMsg(Object obj) {
return "Cannot cast " + obj.getClass().getName() + " to " + getName();
}
/**
* 将此Class对象强制转换为表示指定类对象的子类。检查强制转换是否有效,如果无效则抛出ClassCastException。
* 如果此方法成功,它总是返回对此类对象的引用。
*
* <p>当客户端需要将{@code Class}对象的类型“缩小”以将其传递给API时,此方法非常有用,该API仅接受某些{@code Class}对象。
* 转换会生成编译时警告,因为无法在运行时检查转换的正确性(因为泛型类型是通过擦除实现的)。
*
* @param <U> 将此类对象强制转换为的类型
* @param clazz 要将此类对象强制转换为的类型的类
* @return 对此类对象进行强制转换后表示的子类的{@code Class}对象。
* @throws ClassCastException 如果此{@code Class}对象不表示指定类的子类(这里“子类”包括类本身)。
* @since 1.5
*/
@SuppressWarnings("unchecked")
public <U> Class<? extends U> asSubclass(Class<U> clazz) {
if (clazz.isAssignableFrom(this))
return (Class<? extends U>) this;
else
throw new ClassCastException(this.toString());
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
@SuppressWarnings("unchecked")
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
return (A) annotationData().annotations.get(annotationClass);
}
/**
* {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @since 1.5
*/
@Override
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
return GenericDeclaration.super.isAnnotationPresent(annotationClass);
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
AnnotationData annotationData = annotationData();
return AnnotationSupport.getAssociatedAnnotations(annotationData.declaredAnnotations,
this,
annotationClass);
}
/**
* @since 1.5
*/
public Annotation[] getAnnotations() {
return AnnotationParser.toArray(annotationData().annotations);
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
@SuppressWarnings("unchecked")
public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
return (A) annotationData().declaredAnnotations.get(annotationClass);
}
/**
* @throws NullPointerException {@inheritDoc}
* @since 1.8
*/
@Override
public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass) {
Objects.requireNonNull(annotationClass);
return AnnotationSupport.getDirectlyAndIndirectlyPresent(annotationData().declaredAnnotations,
annotationClass);
}
/**
* @since 1.5
*/
public Annotation[] getDeclaredAnnotations() {
return AnnotationParser.toArray(annotationData().declaredAnnotations);
}
// JVM TI RedefineClasses()调用时可能会失效的注释数据
private static class AnnotationData {
final Map<Class<? extends Annotation>, Annotation> annotations;
final Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
// 创建此AnnotationData实例时的classRedefinedCount的值
final int redefinedCount;
AnnotationData(Map<Class<? extends Annotation>, Annotation> annotations,
Map<Class<? extends Annotation>, Annotation> declaredAnnotations,
int redefinedCount) {
this.annotations = annotations;
this.declaredAnnotations = declaredAnnotations;
this.redefinedCount = redefinedCount;
}
}
// 注释缓存
@SuppressWarnings("UnusedDeclaration")
private volatile transient AnnotationData annotationData;
private AnnotationData annotationData() {
while (true) { // 重试循环
AnnotationData annotationData = this.annotationData;
int classRedefinedCount = this.classRedefinedCount;
if (annotationData != null &&
annotationData.redefinedCount == classRedefinedCount) {
return annotationData;
}
// null或陈旧的annotationData -> 乐观地创建新实例
AnnotationData newAnnotationData = createAnnotationData(classRedefinedCount);
// 尝试安装它
if (Atomic.casAnnotationData(this, annotationData, newAnnotationData)) {
// 成功安装新的AnnotationData
return newAnnotationData;
}
}
}
private AnnotationData createAnnotationData(int classRedefinedCount) {
Map<Class<? extends Annotation>, Annotation> declaredAnnotations =
AnnotationParser.parseAnnotations(getRawAnnotations(), getConstantPool(), this);
Class<?> superClass = getSuperclass();
Map<Class<? extends Annotation>, Annotation> annotations = null;
if (superClass != null) {
Map<Class<? extends Annotation>, Annotation> superAnnotations =
superClass.annotationData().annotations;
for (Map.Entry<Class<? extends Annotation>, Annotation> e : superAnnotations.entrySet()) {
Class<? extends Annotation> annotationClass = e.getKey();
if (AnnotationType.getInstance(annotationClass).isInherited()) {
if (annotations == null) { // 延迟构造
annotations = new LinkedHashMap<>((Math.max(
declaredAnnotations.size(),
Math.min(12, declaredAnnotations.size() + superAnnotations.size())
) * 4 + 2) / 3
);
}
annotations.put(annotationClass, e.getValue());
}
}
}
if (annotations == null) {
// 没有继承的注释 -> 与declaredAnnotations共享Map
annotations = declaredAnnotations;
} else {
// 至少有一个继承的注释 -> declared可以覆盖继承的
annotations.putAll(declaredAnnotations);
}
return new AnnotationData(annotations, declaredAnnotations, classRedefinedCount);
}
// 注释类型缓存其内部(AnnotationType)形式
@SuppressWarnings("UnusedDeclaration")
private volatile transient AnnotationType annotationType;
boolean casAnnotationType(AnnotationType oldType, AnnotationType newType) {
return Atomic.casAnnotationType(this, oldType, newType);
}
AnnotationType getAnnotationType() {
return annotationType;
}
Map<Class<? extends Annotation>, Annotation> getDeclaredAnnotationMap() {
return annotationData().declaredAnnotations;
}
/* 用户定义值的支持类,用于保存与此类相关的值。
* 由ClassValue类维护。
*/
transient ClassValue.ClassValueMap classValueMap;
/**
* 返回表示使用类型指定由此{@code Class}对象表示的实体的超类的{@code AnnotatedType}对象。
* (在'... extends Foo'中使用类型Foo来指定超类是与类型Foo的<em>声明</em>不明确指示带注释的超类不同的。)
*
* <p>如果此{@code Class}对象表示的类型的声明没有明确指示带注释的超类,则返回值是一个表示没有注释的元素的{@code AnnotatedType}对象。
*
* <p>如果此{@code Class}对象表示{@code Object}类、接口类型、数组类型、基本类型或void,则返回值为{@code null}。
*
* @return 表示超类的对象
* @since 1.8
*/
public AnnotatedType getAnnotatedSuperclass() {
if (this == Object.class ||
isInterface() ||
isArray() ||
isPrimitive() ||
this == Void.TYPE) {
return null;
}
return TypeAnnotationParser.buildAnnotatedSuperclass(getRawTypeAnnotations(), getConstantPool(), this);
}
/**
* 返回一个由{@code AnnotatedType}对象组成的数组,用于表示使用类型来指定由此{@code Class}对象表示的实体的超接口。
* (在'... implements Foo'中使用类型Foo来指定的超接口与类型Foo的<em>声明</em>不同。)
*
* <p>如果此{@code Class}对象表示类,则返回的数组包含表示使用接口类型来指定该类实现的接口的对象。
* 数组中对象的顺序与在声明此{@code Class}对象时的'implements'子句中使用的接口类型的顺序相对应。
*
* <p>如果此{@code Class}对象表示接口,则返回的数组包含表示直接扩展的接口的使用接口类型的对象。
* 数组中对象的顺序与在声明此{@code Class}对象时的'extends'子句中使用的接口类型的顺序相对应。
*
* <p>如果此{@code Class}对象表示的类或接口的声明没有明确指示任何带注释的超接口,则返回值是长度为0的数组。
*
* <p>如果此{@code Class}对象表示{@code Object}类、数组类型、基本类型或void,则返回值是长度为0的数组。
*
* @return 表示超接口的数组
* @since 1.8
*/
public AnnotatedType[] getAnnotatedInterfaces() {
return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
}