前言

本文作为 Java 反射机制的一部分,整理了 Class 类中的所有方法,并给出了简单的使用案例作为参考。

版本约定

接下来列举的 Class 类提供的实例方法,默认情况下,指的都是对该 Class 对象所代表的实体(类、接口、数组类、原始类型或 void)的某些操作。

forName

forName 方法有三个重载方法。

  1. public static Class<?> forName(String className) throws ClassNotFoundException
  2. public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException
  3. public static Class<?> forName(Module module, String name)

forName 方法的使用在上面已经提到,就是返回与给定字符串名称的类或接口相关的类对象。

newInstance

@Deprecated(since="9") public T newInstance() throws InstantiationException, IllegalAccessException

newInstance 方法可以用来动态地创建一个类的实例。需要注意的是,它默认使用的是类的无参构造器,如果对应的类中没有提供无参构造器,会抛出异常。

例如,我想创建一个 Student 对象,除了调用 new Student() 这种方式,还可以使用 newlnstance 方法。

  1. public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
  2. Class stuClass = Class.forName("test1.Student");
  3. Student student = (Student) stuClass.newInstance();
  4. }

如果想使用有参的构造器初始化对象,需要使用 Constructor 类中的 newInstance 方法。

另外,在 JDK 9 之后,该方法被标记成过期,推荐使用 Constructor 类中的 newInstance 方法。

isInstance

public boolean isInstance(Object obj)

isInstance 方法和 instanceof 的功能类似,判断指定的对象能否被转换成 Class 对象所代表的类。与 instanceof 主要的区别是 isInstance 方法是 Class 类提供的能力,可以动态的检查对象的类型。

引用官网的描述:This method is the dynamic equivalent of the Java language instanceof operator.

  1. public static void main(String[] args) {
  2. Class stuClass = Student.class;
  3. Class objClass = Object.class;
  4. Student student = new Student();
  5. System.out.println("Student.class.isInstance(student): " + stuClass.isInstance(student));
  6. System.out.println("Object.class.isInstance(student): " + objClass.isInstance(student));
  7. System.out.println("Student.class.isInstance(null): " + stuClass.isInstance(null));
  8. }

运行程序,输出:

  1. Student.class.isInstance(student): true
  2. Object.class.isInstance(student): true
  3. Student.class.isInstance(null): false

isAssignableFrom

public boolean isAssignableFrom(Class<?> cls)

isAssignableFrom 方法判断该实体与指定的 Class 参数所表示的类或接口是否相同,或者是否是其超类或超接口。如果是则返回 true,否则返回 false。

如果这个 Class 对象代表一个基本类型,且指定的 Class 参数正是这个 Class 对象,则该方法返回 true,否则返回 false。

  1. public static void main(String[] args) {
  2. Class stuClass = Student.class;
  3. Class objClass = Object.class;
  4. Class intClass = int.class;
  5. System.out.println("Object.class.isAssignableFrom(Object.class): " + objClass.isAssignableFrom(objClass));
  6. System.out.println("Object.class.isAssignableFrom(Student.class): " + objClass.isAssignableFrom(stuClass));
  7. System.out.println("Object.class.isAssignableFrom(int.class): " + objClass.isAssignableFrom(intClass));
  8. System.out.println("int.class.isAssignableFrom(int.class): " + intClass.isAssignableFrom(int.class));
  9. }

运行程序,输出:

  1. Object.class.isAssignableFrom(Object.class): true
  2. Object.class.isAssignableFrom(Student.class): true
  3. Object.class.isAssignableFrom(int.class): false
  4. int.class.isAssignableFrom(int.class): true

isInterface

public boolean isInterface()

isInterface 方法判断该实体是否是一个接口,如果是则返回 true,否则返回 false。

  1. public static void main(String[] args) {
  2. System.out.println("Map.class.isInterface(): " + Map.class.isInterface());
  3. System.out.println("HashMap.class.isInterface(): " + HashMap.class.isInterface());
  4. }

运行程序,输出:

  1. Map.class.isInterface(): true
  2. HashMap.class.isInterface(): false

isArray

public boolean isArray()

isArray 方法判断该实体是否是一个数组,如果是则返回 true,否则返回 false。

  1. public static void main(String[] args) {
  2. System.out.println("int[].class.isArray(): " + int[].class.isArray());
  3. System.out.println("int.class.isArray(): " + int.class.isArray());
  4. }

运行程序,输出:

  1. int[].class.isArray(): true
  2. int.class.isArray(): false

isPrimitive

public boolean isPrimitive()

isPrimitive 方法判断该实体是否是一个原始类型,如果是则返回 true,否则返回 false。Java 有 9 种原始类型:boolean,byte,char,short,int,long,float,double 和 void。

  1. public static void main(String[] args) {
  2. System.out.println("boolean.class.isPrimitive(): " + boolean.class.isPrimitive());
  3. System.out.println("byte.class.isPrimitive(): " + byte.class.isPrimitive());
  4. System.out.println("char.class.isPrimitive(): " + char.class.isPrimitive());
  5. System.out.println("short.class.isPrimitive(): " + short.class.isPrimitive());
  6. System.out.println("int.class.isPrimitive(): " + int.class.isPrimitive());
  7. System.out.println("long.class.isPrimitive(): " + long.class.isPrimitive());
  8. System.out.println("float.class.isPrimitive(): " + float.class.isPrimitive());
  9. System.out.println("double.class.isPrimitive(): " + double.class.isPrimitive());
  10. System.out.println("void.class.isPrimitive(): " + void.class.isPrimitive());
  11. }

运行程序,输出:

  1. boolean.class.isPrimitive(): true
  2. byte.class.isPrimitive(): true
  3. char.class.isPrimitive(): true
  4. short.class.isPrimitive(): true
  5. int.class.isPrimitive(): true
  6. long.class.isPrimitive(): true
  7. float.class.isPrimitive(): true
  8. double.class.isPrimitive(): true
  9. void.class.isPrimitive(): true

isAnnotation

public boolean isAnnotation()

isAnnotation 方法判断该实体是否是一个注解,如果是则返回 true,否则返回 false。需要注意的是,如果该方法返回 true,则 isInterface 方法也会返回 true,因为所有的注释类型都是接口。

  1. public static void main(String[] args) {
  2. System.out.println("Deprecated.class.isAnnotation(): " + Deprecated.class.isAnnotation());
  3. System.out.println("Deprecated.class.isInterface(): " + Deprecated.class.isInterface());
  4. }

运行程序,输出:

  1. Deprecated.class.isAnnotation(): true
  2. Deprecated.class.isInterface(): true

isSynthetic

public boolean isSynthetic()

isSynthetic 方法判断该实体是否是一个合成类,如果是则返回 true,否则返回 false。

关于什么是合成类,参考 Stack Overflow 中的一些回答:https://stackoverflow.com/questions/399546/synthetic-class-in-java

根据 Stack Overflow 中的一些回答,我们大概可以知道合成类是由 Java 编译器生成的,不存在源码中。另外,匿名类和代理类都不是合成类,Java 8 中的 lambda 可以生成合成类。

  1. public static void main(String[] args) {
  2. Runnable r1 = new Runnable() {
  3. @Override
  4. public void run() {
  5. }
  6. };
  7. Runnable r2 = () -> {
  8. };
  9. System.out.println("r1.isSynthetic(): " + r1.getClass().isSynthetic());
  10. System.out.println("r2.isSynthetic(): " + r2.getClass().isSynthetic());
  11. }

运行程序,输出:

  1. r1.isSynthetic(): false
  2. r2.isSynthetic(): true

getName

public String getName()

getName 方法返回该实体的名称。

  • 如果这个 Class 对象代表一个非数组类型的引用类型,则该方法将返回该类型的二进制名称(包名+类名的字符串);
  • 如果这个 Class 对象代表一个原始类型或 void,则该方法将返回原始类型或 void 对应的 Java 语言关键字的字符串;
  • 如果这个 Class 对象代表一个数组类,则该方法返回的名称类似:[[[[[[[I,前面有一个或多个 ‘[‘ 字符代表数组嵌套的深度,内部是元素类型名称的编码。

元素类型名称的编码方式如下:

元素类型 编码
boolean Z
byte B
char C
class or interface Lclassname;
double D
float F
int I
long J
short S
  1. public static void main(String[] args) {
  2. System.out.println("String.class.getName(): " + String.class.getName());
  3. System.out.println("byte.class.getName(): " + byte.class.getName());
  4. System.out.println("(new Object[3]).getClass().getName(): " + (new Object[3]).getClass().getName());
  5. System.out.println("(new int[3][4][5][6][7][8][9]).getClass().getName(): " + (new int[3][4][5][6][7][8][9]).getClass().getName());
  6. }

运行程序,输出:

  1. String.class.getName(): java.lang.String
  2. byte.class.getName(): byte
  3. (new Object[3]).getClass().getName(): [Ljava.lang.Object;
  4. (new int[3][4][5][6][7][8][9]).getClass().getName(): [[[[[[[I

getClassLoader

public ClassLoader getClassLoader()

getClassLoader 方法返回加载该实体的类加载器。比如,new Student().getClass().getClassLoader() 返回加载 Student 类的类加载器。

如果一个类是通过 bootstrap class loader 加载的,通过这个方法获得 class loader 时,有些 JDK 的实现是会返回一个 null 的。另外,如果这个 Class 对象代表一个原始类型或 void,也会返回 null。

  1. public static void main(String[] args) {
  2. System.out.println("new Student().getClass().getClassLoader():" + new Student().getClass().getClassLoader());
  3. System.out.println("int.class.getClassLoader(): " + int.class.getClassLoader());
  4. System.out.println("void.class.getClassLoader(): " + void.class.getClassLoader());
  5. }

运行程序,输出:

  1. new Student().getClass().getClassLoader():jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
  2. int.class.getClassLoader(): null
  3. void.class.getClassLoader(): null

getModule

public Module getModule()

Java 9 在 packages 之上引入了一个新的抽象级别,称为 Java Platform Module System (JPMS),简称 Modules。

getModule 方法返回该实体的所属模块。

  • 如果这个 Class 对象代表一个数组类型,则该方法返回数组中元素类型的模块;
  • 如果这个 Class 对象代表一个原始类型或 void,则该方法将返回 java.base 模块的 Module 对象;
  • 如果这个 Class 对象在一个未命名的模块中,则该方法将返回一个未命名模块。
    1. public static void main(String[] args) {
    2. System.out.println("int.class.getModule(): " + int.class.getModule());
    3. System.out.println("new int[10].getClass().getModule(): " + new int[10].getClass().getModule());
    4. System.out.println("Student.class.getModule(): " + Student.class.getModule());
    5. }
    运行程序,输出:
    1. int.class.getModule(): module java.base
    2. new int[10].getClass().getModule(): module java.base
    3. Student.class.getModule(): unnamed module @234bef66

    getTypeParameters

public TypeVariable<Class<T>>[] getTypeParameters()

getTypeParameters 方法返回一个 TypeVariable 对象的数组,该数组代表由 GenericDeclaration 对象代表的泛型声明所声明的类型变量,按声明顺序排列。如果底层泛型声明没有声明任何类型变量,则返回一个长度为 0 的数组。

  1. public static void main(String[] args) {
  2. System.out.println("List.class.getTypeParameters(): " + Arrays.toString(List.class.getTypeParameters()));
  3. System.out.println("Map.class.getTypeParameters(): " + Arrays.toString(Map.class.getTypeParameters()));
  4. }

运行程序,输出:

  1. List.class.getTypeParameters(): [E]
  2. Map.class.getTypeParameters(): [K, V]

getSuperclass

public Class<? super T> getSuperclass()

getSuperclass 方法返回该实体的直接父类。

  • 如果这个 Class 对象代表 Object 类,一个接口,一个原始类型,或者是 void,那则该方法返回 null;
  • 如果这个 Class 对象代表一个数组类,则该方法返回 Object 类的 Class 对象。
    1. public static void main(String[] args) {
    2. System.out.println("ArrayList.class.getSuperclass(): " + ArrayList.class.getSuperclass());
    3. System.out.println("Object.class.getSuperclass(): " + Object.class.getSuperclass());
    4. System.out.println("List.class.getSuperclass(): " + List.class.getSuperclass());
    5. System.out.println("int.class.getSuperclass(): " + int.class.getSuperclass());
    6. System.out.println("void.class.getSuperclass(): " + void.class.getSuperclass());
    7. System.out.println("int[].class.getSuperclass(): " + int[].class.getSuperclass());
    8. }
    运行程序,输出:
    1. ArrayList.class.getSuperclass(): class java.util.AbstractList
    2. Object.class.getSuperclass(): null
    3. List.class.getSuperclass(): null
    4. int.class.getSuperclass(): null
    5. void.class.getSuperclass(): null
    6. int[].class.getSuperclass(): class java.lang.Object

    getGenericSuperclass

public Type getGenericSuperclass()

getGenericSuperclass 方法返回该实体直接父类的 Type 对象。getGenericSuperclass 方法在 getSuperclass 方法的基础上,还可以获得直接父类的泛型参数的实际类型。

  1. class CustomList extends ArrayList<String> {
  2. }
  3. public static void main(String[] args) {
  4. System.out.println("ArrayList.class.getGenericSuperclass(): " + ArrayList.class.getGenericSuperclass());
  5. System.out.println("Object.class.getGenericSuperclass(): " + Object.class.getGenericSuperclass());
  6. System.out.println("List.class.getGenericSuperclass(): " + List.class.getGenericSuperclass());
  7. System.out.println("int.class.getGenericSuperclass(): " + int.class.getGenericSuperclass());
  8. System.out.println("void.class.getGenericSuperclass(): " + void.class.getGenericSuperclass());
  9. System.out.println("int[].class.getGenericSuperclass(): " + int[].class.getGenericSuperclass());
  10. System.out.println("CustomList.class.getGenericSuperclass(): " + CustomList.class.getGenericSuperclass());
  11. }

运行程序,输出:

  1. ArrayList.class.getGenericSuperclass(): java.util.AbstractList<E>
  2. Object.class.getGenericSuperclass(): null
  3. List.class.getGenericSuperclass(): null
  4. int.class.getGenericSuperclass(): null
  5. void.class.getGenericSuperclass(): null
  6. int[].class.getGenericSuperclass(): class java.lang.Object
  7. CustomList.class.getGenericSuperclass(): java.util.ArrayList<java.lang.String>

增加一个补充案例,获取泛型类中的泛型参数的实际类型。

  1. class CustomMap extends HashMap<Integer, String> {}
  2. public static void main(String[] args) {
  3. Type genericSuperclass = CustomMap.class.getGenericSuperclass();
  4. Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
  5. System.out.println("actualTypeArguments: " + Arrays.toString(actualTypeArguments));
  6. }

运行程序,输出:

  1. actualTypeArguments: [class java.lang.Integer, class java.lang.String]

getPackage

public Package getPackage()

getPackage 方法返回该实体的 Package 对象。如果这个 Class 代表一个数组类型,一个原始类型或 void,这个方法返回 null。

  1. public static void main(String[] args) {
  2. System.out.println("String.class.getPackage(): " + String.class.getPackage());
  3. System.out.println("String[].class.getPackage(): " + String[].class.getPackage());
  4. System.out.println("int.class.getPackage(): " + int.class.getPackage());
  5. System.out.println("void.class.getPackage(): " + void.class.getPackage());
  6. }

运行程序,输出:

  1. String.class.getPackage(): package java.lang
  2. String[].class.getPackage(): null
  3. int.class.getPackage(): null
  4. void.class.getPackage(): null

getPackageName

public String getPackageName()

getPackageName 方法返回该实体的包名。

  • 如果这个 Class 对象代表一个顶层类,则该方法将返回该类所属包的全称,如果该类在一个未命名的包中,则返回空字符串;
  • 如果这个 Class 对象代表一个内部类,则该方法就相当于在外部类上调用 getPackageName();
  • 如果这个类是一个局部类或匿名类,则该方法就相当于对包装方法或包装构造函数的声明类调用getPackageName();
  • 如果这个 Class 对象代表一个数组类型,则该方法返回元素类型的包名;
  • 如果这个 Class 对象代表一个原始类型或 void,则该方法将返回包名 “java.lang”。 ```java class TestA { }

interface TestB { }

public static void main(String[] args) { System.out.println(“List.class.getPackageName(): “ + List.class.getPackageName()); System.out.println(“TestA.class.getPackageName(): “ + TestA.class.getPackageName()); System.out.println(“new TestB() {}.getClass().getPackageName(): “ + new TestB() {}.getClass().getPackageName()); System.out.println(“int.class.getPackageName(): “ + int.class.getPackageName()); System.out.println(“String[].class.getPackageName(): “ + String[].class.getPackageName()); }

  1. 运行程序,输出:

List.class.getPackageName(): java.util TestA.class.getPackageName(): test13 new TestB() {}.getClass().getPackageName(): test13 int.class.getPackageName(): java.lang String[].class.getPackageName(): java.lang

  1. <a name="fNWLw"></a>
  2. ## getInterfaces
  3. `public Class<?>[] getInterfaces()`
  4. getInterfaces 方法返回该实体直接实现的接口。
  5. - 如果这个 Class 对象代表一个类,则返回值是一个数组,它包含了该类所实现的所有接口。数组中接口的顺序与该类 implements 子句中的接口名顺序一致。例如,给定声明:
  6. ```java
  7. class Shimmer implements FloorWax, DessertTopping { ... }

假设 s 的值为 Shimmer 的一个实例,表达式:

  1. s.getClass().getInterfaces()[0];

的值为表示 FloorWax 接口的 Class 对象。

  1. s.getClass().getInterfaces()[1];

的值为表示 DessertTopping 接口的 Class 对象。

  • 如果这个 Class 对象代表一个接口,则该数组包含表示该接口扩展的所有接口的对象。数组中接口对象顺序与此对象所表示的接口的声明的 extends 子句中接口名顺序一致;
  • 如果这个 Class 对象代表一个不实现任何接口的类或接口,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个原始类型或 void,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个数组类型,则该方法返回一个包含接口 Cloneable 和 java.io.Serializable 的数组。
    1. public static void main(String[] args) {
    2. System.out.println("ArrayList.class.getInterfaces(): " + Arrays.toString(ArrayList.class.getInterfaces()));
    3. System.out.println("List.class.getInterfaces(): " + Arrays.toString(List.class.getInterfaces()));
    4. System.out.println("Student.class.getInterfaces(): " + Arrays.toString(Student.class.getInterfaces()));
    5. System.out.println("void.class.getInterfaces(): " + Arrays.toString(void.class.getInterfaces()));
    6. System.out.println("int[].class.getInterfaces(): " + Arrays.toString(int[].class.getInterfaces()));
    7. }
    运行程序,输出:
    1. ArrayList.class.getInterfaces(): [interface java.util.List, interface java.util.RandomAccess, interface java.lang.Cloneable, interface java.io.Serializable]
    2. List.class.getInterfaces(): [interface java.util.Collection]
    3. Student.class.getInterfaces(): []
    4. void.class.getInterfaces(): []
    5. int[].class.getInterfaces(): [interface java.lang.Cloneable, interface java.io.Serializable]

    getGenericInterfaces

public Type[] getGenericInterfaces()

getGenericInterfaces 方法返回该实体直接实现接口的 Type 对象。getGenericInterfaces 方法在 getInterfaces 方法的基础上,还可以获得实现接口的泛型参数的实际类型。

  • 如果实现的接口是一个参数化类型,则返回的 Type 对象必须准确反映源代码中所使用的实际类型参数;
  • 如果这个 Class 对象代表一个类,则返回一个数组,该数组包含该类直接实现的所有接口。数组中接口对象顺序与此对象所表示的类的声明的 implements 子句中接口名顺序一致;
  • 如果这个 Class 对象代表一个没有实现任何接口的类或接口,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个原始类型或 void,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个数组类型,则该方法返回一个包含接口 Cloneable 和 java.io.Serializable 的数组。
    1. public static void main(String[] args) {
    2. System.out.println("ArrayList.class.getGenericInterfaces(): " + Arrays.toString(ArrayList.class.getGenericInterfaces()));
    3. System.out.println("List.class.getGenericInterfaces(): " + Arrays.toString(List.class.getGenericInterfaces()));
    4. System.out.println("Student.class.getGenericInterfaces(): " + Arrays.toString(Student.class.getGenericInterfaces()));
    5. System.out.println("void.class.getGenericInterfaces(): " + Arrays.toString(void.class.getGenericInterfaces()));
    6. System.out.println("int[].class.getGenericInterfaces(): " + Arrays.toString(int[].class.getGenericInterfaces()));
    7. }
    运行程序,输出:
    1. ArrayList.class.getGenericInterfaces(): [java.util.List<E>, interface java.util.RandomAccess, interface java.lang.Cloneable, interface java.io.Serializable]
    2. List.class.getGenericInterfaces(): [java.util.Collection<E>]
    3. Student.class.getGenericInterfaces(): []
    4. void.class.getGenericInterfaces(): []
    5. int[].class.getGenericInterfaces(): [interface java.lang.Cloneable, interface java.io.Serializable]

    getComponentType

public Class<?> getComponentType()

  • 如果这个 Class 对象代表一个数组类型,则该方法返回表示一个数组的组件类型的 Class。
  • 如果这个 Class 对象不代表一个数组类型,则该方法返回 null。
    1. public static void main(String[] args) {
    2. System.out.println("int[].class.getComponentType(): " + int[].class.getComponentType());
    3. System.out.println("String[].class.getComponentType(): " + String[].class.getComponentType());
    4. System.out.println("List.class.getComponentType(): " + List.class.getComponentType());
    5. }
    运行程序,输出:
    1. int[].class.getComponentType(): int
    2. String[].class.getComponentType(): class java.lang.String
    3. List.class.getComponentType(): null

    getModifiers

public int getModifiers()

getModifiers 方法返回该实体的 Java 语言修饰符,以整数形式编码。这些修饰符由 Java 虚拟机的 public、protected、private、final、static、abstract 和 interface 的常量组成,可以用 Modifier 类中的方法进行解码。

  1. public static void main(String[] args) {
  2. System.out.println("List.class.getModifiers(): " + List.class.getModifiers());
  3. System.out.println("Modifier.toString(List.class.getModifiers()): " + Modifier.toString(List.class.getModifiers()));
  4. }

运行程序,输出:

  1. List.class.getModifiers(): 1537
  2. Modifier.toString(List.class.getModifiers()): public abstract interface

getSigners

public Object[] getSigners()

getSigners 方法返回该实体的签名者。如果没有签名者,则返回 null。如果这个 Class 对象代表一个原始类型或 void,则该方法返回 null。

  1. public static void main(String[] args) {
  2. System.out.println("List.class.getSigners(): " + List.class.getSigners());
  3. System.out.println("int.class.getSigners(): " + int.class.getSigners());
  4. }

运行程序,输出:

  1. List.class.getSigners(): null
  2. int.class.getSigners(): null

getEnclosingMethod

public Method getEnclosingMethod() throws SecurityException

如果该实体代表一个局部内部类或匿名内部类,则 getEnclosingMethod 方法返回一个 Method 对象,该 Method 对象代表外部类创建该实体的方法。

如果该实体代表的局部内部类或匿名内部类不是通过方法创建,而是通过实例声明、实例初始化块、静态初始化块或构造函数创建,则该方法将返回 null。

  1. public class Test25 {
  2. private Runnable runnable1 = new Runnable() {
  3. @Override
  4. public void run() {
  5. }
  6. };
  7. private Runnable runnable2;
  8. {
  9. runnable2 = new Runnable() {
  10. @Override
  11. public void run() {
  12. }
  13. };
  14. }
  15. private Runnable runnable3;
  16. public Test25() {
  17. runnable3 = new Runnable() {
  18. @Override
  19. public void run() {
  20. }
  21. };
  22. }
  23. private static Runnable runnable4 = new Runnable() {
  24. @Override
  25. public void run() {
  26. }
  27. };
  28. private static Runnable runnable5;
  29. static {
  30. runnable5 = new Runnable() {
  31. @Override
  32. public void run() {
  33. }
  34. };
  35. }
  36. public Runnable getRunnable6() {
  37. return new Runnable() {
  38. @Override
  39. public void run() {
  40. }
  41. };
  42. }
  43. public static void main(String[] args) {
  44. Runnable runnable7 = new Runnable() {
  45. @Override
  46. public void run() {
  47. }
  48. };
  49. Test25 test25 = new Test25();
  50. System.out.println("runnable1.getClass().getEnclosingMethod(): " + test25.runnable1.getClass().getEnclosingMethod());
  51. System.out.println("runnable2.getClass().getEnclosingMethod(): " + test25.runnable2.getClass().getEnclosingMethod());
  52. System.out.println("runnable3.getClass().getEnclosingMethod(): " + test25.runnable3.getClass().getEnclosingMethod());
  53. System.out.println("runnable4.getClass().getEnclosingMethod(): " + runnable4.getClass().getEnclosingMethod());
  54. System.out.println("runnable5.getClass().getEnclosingMethod(): " + runnable5.getClass().getEnclosingMethod());
  55. System.out.println("runnable6.getClass().getEnclosingMethod(): " + test25.getRunnable6().getClass().getEnclosingMethod());
  56. System.out.println("runnable7.getClass().getEnclosingMethod(): " + runnable7.getClass().getEnclosingMethod());
  57. }
  58. }

运行程序,输出:

  1. runnable1.getClass().getEnclosingMethod(): null
  2. runnable2.getClass().getEnclosingMethod(): null
  3. runnable3.getClass().getEnclosingMethod(): null
  4. runnable4.getClass().getEnclosingMethod(): null
  5. runnable5.getClass().getEnclosingMethod(): null
  6. runnable6.getClass().getEnclosingMethod(): public java.lang.Runnable test13.Test25.getRunnable6()
  7. runnable7.getClass().getEnclosingMethod(): public static void test13.Test25.main(java.lang.String[])

getEnclosingConstructor

public Constructor<?> getEnclosingConstructor() throws SecurityException

如果该实体代表一个局部内部类或匿名内部类,则 getEnclosingConstructor 方法返回一个 Constructor 对象,该 Constructor 对象代表外部类创建该实体的构造函数。

如果该实体代表的局部内部类或匿名内部类不是通过构造函数创建,而是通过实例声明、实例初始化块、静态初始化块或方法创建,则该方法将返回 null。

  1. public class Test26 {
  2. private Runnable runnable1 = new Runnable() {
  3. @Override
  4. public void run() {
  5. }
  6. };
  7. private Runnable runnable2;
  8. {
  9. runnable2 = new Runnable() {
  10. @Override
  11. public void run() {
  12. }
  13. };
  14. }
  15. private Runnable runnable3;
  16. public Test26() {
  17. runnable3 = new Runnable() {
  18. @Override
  19. public void run() {
  20. }
  21. };
  22. }
  23. private static Runnable runnable4 = new Runnable() {
  24. @Override
  25. public void run() {
  26. }
  27. };
  28. private static Runnable runnable5;
  29. static {
  30. runnable5 = new Runnable() {
  31. @Override
  32. public void run() {
  33. }
  34. };
  35. }
  36. public Runnable getRunnable6() {
  37. return new Runnable() {
  38. @Override
  39. public void run() {
  40. }
  41. };
  42. }
  43. public static void main(String[] args) {
  44. Runnable runnable7 = new Runnable() {
  45. @Override
  46. public void run() {
  47. }
  48. };
  49. Test26 test26 = new Test26();
  50. System.out.println("runnable1.getClass().getEnclosingConstructor(): " + test26.runnable1.getClass().getEnclosingConstructor());
  51. System.out.println("runnable2.getClass().getEnclosingConstructor(): " + test26.runnable2.getClass().getEnclosingConstructor());
  52. System.out.println("runnable3.getClass().getEnclosingConstructor(): " + test26.runnable3.getClass().getEnclosingConstructor());
  53. System.out.println("runnable4.getClass().getEnclosingConstructor(): " + runnable4.getClass().getEnclosingConstructor());
  54. System.out.println("runnable5.getClass().getEnclosingConstructor(): " + runnable5.getClass().getEnclosingConstructor());
  55. System.out.println("runnable6.getClass().getEnclosingConstructor(): " + test26.getRunnable6().getClass().getEnclosingConstructor());
  56. System.out.println("runnable7.getClass().getEnclosingConstructor(): " + runnable7.getClass().getEnclosingConstructor());
  57. }
  58. }

运行程序,输出:

  1. runnable1.getClass().getEnclosingConstructor(): null
  2. runnable2.getClass().getEnclosingConstructor(): null
  3. runnable3.getClass().getEnclosingConstructor(): public test13.Test26()
  4. runnable4.getClass().getEnclosingConstructor(): null
  5. runnable5.getClass().getEnclosingConstructor(): null
  6. runnable6.getClass().getEnclosingConstructor(): null
  7. runnable7.getClass().getEnclosingConstructor(): null

getDeclaringClass

public Class<?> getDeclaringClass() throws SecurityException

  • 如果这个 Class 对象所代表的类或接口是另一个类的成员,则该方法返回代表它被声明的类的 Class 对象;
  • 如果这个类或接口不是任何其他类的成员,则该方法返回 null;
  • 如果这个 Class 对象代表一个数组类型,一个原始类型,或者是 void,则该方法返回 null。

    1. public class Test2 {
    2. public class MemberInnerClass {
    3. public class MemberInnerInnerClass {
    4. }
    5. }
    6. public static class StaticInnerClass {
    7. }
    8. public static void main(String[] args) {
    9. Runnable anonymousInnerClass = new Runnable() {
    10. @Override
    11. public void run() {
    12. }
    13. };
    14. class LocalInnerClass {
    15. }
    16. System.out.println("MemberInnerClass.class.getDeclaringClass(): " + MemberInnerClass.class.getDeclaringClass());
    17. System.out.println("MemberInnerClass.MemberInnerInnerClass.class.getDeclaringClass(): " + MemberInnerClass.MemberInnerInnerClass.class.getDeclaringClass());
    18. System.out.println("StaticInnerClass.class.getDeclaringClass(): " + StaticInnerClass.class.getDeclaringClass());
    19. System.out.println("anonymousInnerClass.getClass().getDeclaringClass(): " + anonymousInnerClass.getClass().getDeclaringClass());
    20. System.out.println("LocalInnerClass.class.getDeclaringClass(): " + LocalInnerClass.class.getDeclaringClass());
    21. }
    22. }

    运行程序,输出:

    1. MemberInnerClass.class.getDeclaringClass(): class test14.Test2
    2. MemberInnerClass.MemberInnerInnerClass.class.getDeclaringClass(): class test14.Test2$MemberInnerClass
    3. StaticInnerClass.class.getDeclaringClass(): class test14.Test2
    4. anonymousInnerClass.getClass().getDeclaringClass(): null
    5. LocalInnerClass.class.getDeclaringClass(): null

    getEnclosingClass

public Class<?> getEnclosingClass() throws SecurityException

getEnclosingClass 方法返回该实体的外部类的 Class 对象。和 getDeclaringClass 方法的功能类似,只是 getEnclosingClass 还可以获取匿名内部类和局部内部类的外部类的 Class 对象。

  1. public class Test3 {
  2. public class MemberInnerClass {
  3. public class MemberInnerInnerClass {
  4. }
  5. }
  6. public static class StaticInnerClass {
  7. }
  8. public static void main(String[] args) {
  9. Runnable anonymousInnerClass = new Runnable() {
  10. @Override
  11. public void run() {
  12. }
  13. };
  14. class LocalInnerClass {
  15. }
  16. System.out.println("MemberInnerClass.class.getEnclosingClass(): " + MemberInnerClass.class.getEnclosingClass());
  17. System.out.println("MemberInnerClass.MemberInnerInnerClass.class.getEnclosingClass(): " + MemberInnerClass.MemberInnerInnerClass.class.getEnclosingClass());
  18. System.out.println("StaticInnerClass.class.getEnclosingClass(): " + StaticInnerClass.class.getEnclosingClass());
  19. System.out.println("anonymousInnerClass.getClass().getEnclosingClass(): " + anonymousInnerClass.getClass().getEnclosingClass());
  20. System.out.println("LocalInnerClass.class.getEnclosingClass(): " + LocalInnerClass.class.getEnclosingClass());
  21. }
  22. }

运行程序,输出:

  1. MemberInnerClass.class.getEnclosingClass(): class test14.Test3
  2. MemberInnerClass.MemberInnerInnerClass.class.getEnclosingClass(): class test14.Test3$MemberInnerClass
  3. StaticInnerClass.class.getEnclosingClass(): class test14.Test3
  4. anonymousInnerClass.getClass().getEnclosingClass(): class test14.Test3
  5. LocalInnerClass.class.getEnclosingClass(): class test14.Test3

getSimpleName

public String getSimpleName()

getSimpleName 方法返回该实体的简单名称。

  • 如果这个 Class 对象代表一个匿名内部类,则返回一个空字符串;
  • 如果这个 Class 对象代表一个数组类型,则返回一个带有 “[]” 的组件类型的简单名称,特别是,如果这个数组的组件类型是匿名的,则返回 “[]” 字符串。
    1. public static void main(String[] args) {
    2. System.out.println("List.class.getSimpleName(): " + List.class.getSimpleName());
    3. System.out.println("int[].class.getSimpleName(): " + int[].class.getSimpleName());
    4. }
    运行程序,输出:
    1. List.class.getSimpleName(): List
    2. int[].class.getSimpleName(): int[]

    getTypeName

public String getTypeName()

getTypeName 方法返回该实体的类型名称。

  • 如果这个 Class 对象代表一个数组类型,则返回一个带有 “[]” 的组件类型的类型名称;
  • 如果这个 Class 对象不是代表数组类型,则返回 getName 方法获得的值。
    1. public static void main(String[] args) {
    2. System.out.println("int.class.getTypeName(): " + int.class.getTypeName());
    3. System.out.println("List.class.getTypeName(): " + List.class.getTypeName());
    4. System.out.println("int[].class.getTypeName(): " + int[].class.getTypeName());
    5. System.out.println("String[].class.getTypeName(): " + String[].class.getTypeName());
    6. }
    运行程序,输出:
    1. int.class.getTypeName(): int
    2. List.class.getTypeName(): java.util.List
    3. int[].class.getTypeName(): int[]
    4. String[].class.getTypeName(): java.lang.String[]

    getCanonicalName

public String getCanonicalName()

getCanonicalName 方法返回该实体的 Java 语言规范定义的底层类的规范名称。如果这个 Class 对象代表一个本地类,或是一个匿名类,或是一个组件类型没有规范名称的数组,则返回 null。

  1. public class Test7 {
  2. public static void main(String[] args) {
  3. class LocalClass {
  4. }
  5. Runnable runnable = new Runnable() {
  6. @Override
  7. public void run() {
  8. }
  9. };
  10. System.out.println("int.class.getCanonicalName(): " + int.class.getCanonicalName());
  11. System.out.println("List.class.getCanonicalName(): " + List.class.getCanonicalName());
  12. System.out.println("Student.class.getCanonicalName(): " + Student.class.getCanonicalName());
  13. System.out.println("LocalClass.class.getCanonicalName(): " + LocalClass.class.getCanonicalName());
  14. System.out.println("runnable.getClass().getCanonicalName(): " + runnable.getClass().getCanonicalName());
  15. System.out.println("int[].class.getCanonicalName(): " + int[].class.getCanonicalName());
  16. System.out.println("String[].class.getCanonicalName(): " + String[].class.getCanonicalName());
  17. System.out.println("Student[].class.getCanonicalName(): " + Student[].class.getCanonicalName());
  18. System.out.println("LocalClass[].class.getCanonicalName(): " + LocalClass[].class.getCanonicalName());
  19. }
  20. }

运行程序,输出:

  1. int.class.getCanonicalName(): int
  2. List.class.getCanonicalName(): java.util.List
  3. Student.class.getCanonicalName(): test1.Student
  4. LocalClass.class.getCanonicalName(): null
  5. runnable.getClass().getCanonicalName(): null
  6. int[].class.getCanonicalName(): int[]
  7. String[].class.getCanonicalName(): java.lang.String[]
  8. Student[].class.getCanonicalName(): test1.Student[]
  9. LocalClass[].class.getCanonicalName(): null

isAnonymousClass

public boolean isAnonymousClass()

isAnonymousClass 方法判断该实体是否是一个匿名类,如果是则返回 true,否则返回 false。

  1. public class Test8 {
  2. public static void main(String[] args) {
  3. class LocalClass {
  4. }
  5. Runnable runnable = new Runnable() {
  6. @Override
  7. public void run() {
  8. }
  9. };
  10. System.out.println("List.class.isAnonymousClass(): " + List.class.isAnonymousClass());
  11. System.out.println("LocalClass.class.isAnonymousClass(): " + LocalClass.class.isAnonymousClass());
  12. System.out.println("runnable.getClass().isAnonymousClass(): " + runnable.getClass().isAnonymousClass());
  13. }
  14. }

运行程序,输出:

  1. List.class.isAnonymousClass(): false
  2. LocalClass.class.isAnonymousClass(): false
  3. runnable.getClass().isAnonymousClass(): true

isLocalClass

public boolean isLocalClass()

isLocalClass 方法判断该实体是否是一个本地类,如果是则返回 true,否则返回 false。

  1. public class Test9 {
  2. public static void main(String[] args) {
  3. class LocalClass {
  4. }
  5. Runnable runnable = new Runnable() {
  6. @Override
  7. public void run() {
  8. }
  9. };
  10. System.out.println("List.class.isLocalClass(): " + List.class.isLocalClass());
  11. System.out.println("LocalClass.class.isLocalClass(): " + LocalClass.class.isLocalClass());
  12. System.out.println("runnable.getClass().isLocalClass(): " + runnable.getClass().isLocalClass());
  13. }
  14. }

运行程序,输出:

  1. List.class.isLocalClass(): false
  2. LocalClass.class.isLocalClass(): true
  3. runnable.getClass().isLocalClass(): false

isMemberClass

public boolean isMemberClass()

isMemberClass 方法判断该实体是否是一个成员类,如果是则返回 true,否则返回 false。如果这个 Class 对象代表一个本地类,或是一个匿名类,则返回 false。

  1. public class Test11 {
  2. public class MemberInnerClass {
  3. public class MemberInnerInnerClass {
  4. }
  5. }
  6. public static class StaticInnerClass {
  7. }
  8. public static void main(String[] args) {
  9. class LocalClass {
  10. }
  11. Runnable runnable = new Runnable() {
  12. @Override
  13. public void run() {
  14. }
  15. };
  16. System.out.println("MemberInnerClass.MemberInnerInnerClass.class.isMemberClass(): " + MemberInnerClass.MemberInnerInnerClass.class.isMemberClass());
  17. System.out.println("MemberInnerClass.class.isMemberClass(): " + MemberInnerClass.class.isMemberClass());
  18. System.out.println("StaticInnerClass.class.isMemberClass(): " + StaticInnerClass.class.isMemberClass());
  19. System.out.println("LocalClass.class.isMemberClass(): " + LocalClass.class.isMemberClass());
  20. System.out.println("runnable.getClass().isMemberClass(): " + runnable.getClass().isMemberClass());
  21. }
  22. }

运行程序,输出:

  1. MemberInnerClass.MemberInnerInnerClass.class.isMemberClass(): true
  2. MemberInnerClass.class.isMemberClass(): true
  3. StaticInnerClass.class.isMemberClass(): true
  4. LocalClass.class.isMemberClass(): false
  5. runnable.getClass().isMemberClass(): false

getClasses

public Class<?>[] getClasses()

getClasses 方法返回该实体的所有公共成员类和成员接口,包括从父类继承的。

  • 如果这个 Class 对象没有公共成员类和成员接口,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法也返回一个长度为 0 的数组。 ```java public class Test13 {

    public class MemberInnerClass3 {

    } }

public class Test12 extends Test13 {

  1. public class MemberInnerClass {
  2. }
  3. private class MemberInnerClass2 {
  4. }
  5. public static class StaticInnerClass {
  6. }
  7. public static void main(String[] args) {
  8. class LocalClass {
  9. }
  10. Runnable runnable = new Runnable() {
  11. @Override
  12. public void run() {
  13. }
  14. };
  15. System.out.println("Test12.class.getClasses(): " + Arrays.toString(Test12.class.getClasses()));
  16. }

}

  1. 运行程序,输出:

Test12.class.getClasses(): [class test14.Test12$StaticInnerClass, class test14.Test12$MemberInnerClass, class test14.Test13$MemberInnerClass3]

  1. <a name="pYbh1"></a>
  2. ## getFields
  3. `public Field[] getFields() throws SecurityException`
  4. getFields 方法返回该实体声明的所有公共字段(public field),包括从父类和父接口继承的公共字段,不返回私有字段(private field)。
  5. - 如果这个 Class 对象代表一个没有可访问公共字段的类或接口,则该方法返回一个长度为 0 的数组;
  6. - 如果这个 Class 对象代表一个类,则该方法返回这个类以及它的所有父类和父接口的公共字段;
  7. - 如果这个 Class 对象代表一个接口,则该方法返回这个接口及其所有父接口的字段;
  8. - 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。
  9. 返回的数组中的元素没有被排序,也没有任何特定的顺序。
  10. ```java
  11. public class Test14 {
  12. private String privateField;
  13. public String publicField;
  14. public static void main(String[] args) {
  15. System.out.println("Test14.class.getFields(): " + Arrays.toString(Test14.class.getFields()));
  16. }
  17. }

运行程序,输出:

  1. Test14.class.getFields(): [public java.lang.String test14.Test14.publicField]

getMethods

public Method[] getMethods() throws SecurityException

getMethods 方法返回该实体的所有公共方法(public method),包括从父类和父接口继承的公共方法,不返回私有方法(private method)。

  • 如果这个 Class 对象代表一个数组类型,则该方法返回 Object 类中除了 clone() 的所有公共方法;
  • 如果这个 Class 对象代表一个接口,则该方法不返回 Object 类中的任何方法。因此,如果该接口或其任意父接口中没有声明方法,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个类,则该方法始终返回从 Object 类继承的除了 clone() 的所有公共方法。

返回的数组中的元素没有被排序,也没有任何特定的顺序。

  1. public class Test15 {
  2. private void privateMethod() {
  3. }
  4. public void publicMethod() {
  5. }
  6. public static void main(String[] args) {
  7. System.out.println("Test15.class.getMethods(): " + Arrays.toString(Test15.class.getMethods()));
  8. System.out.println("int[].class.getMethods(): " + Arrays.toString(int[].class.getMethods()));
  9. }
  10. }

运行程序,输出:

  1. Test15.class.getMethods(): [public static void test14.Test15.main(java.lang.String[]), public void test14.Test15.publicMethod(), public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
  2. int[].class.getMethods(): [public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final void java.lang.Object.wait() throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]

getConstructors

public Constructor<?>[] getConstructors() throws SecurityException

getConstructors 方法返回该实体(类)声明的所有公共构造函数(public constructor)。

  • 如果这个 Class 对象代表一个没有公共构造函数的类,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。

    1. public class Test16 {
    2. public Test16() {
    3. }
    4. public static void main(String[] args) {
    5. System.out.println("Test16.class.getConstructors(): " + Arrays.toString(Test16.class.getConstructors()));
    6. System.out.println("int.class.getConstructors(): " + Arrays.toString(int.class.getConstructors()));
    7. System.out.println("String[].class.getConstructors(): " + Arrays.toString(String[].class.getConstructors()));
    8. }
    9. }

    运行程序,输出:

    1. Test16.class.getConstructors(): [public test14.Test16()]
    2. int.class.getConstructors(): []
    3. String[].class.getConstructors(): []

    getField

public Field getField(String name) throws NoSuchFieldException, SecurityException

getField 方法返回该实体的指定公共成员字段(public field)。参数 name 是一个字符串,指定所需字段的简单名称。

返回的 Field 对象由以下算法确定。假设 C 是 Class 对象所表示的类或者接口:

  1. 如果 C 声明了该指定名称的公共字段,则返回该 Field 对象;
  2. 如果在上述步骤 1 中未找到任何字段,则将此算法递归应用于 C 的每个直接父接口,直接父接口按其声明的顺序进行搜索;
  3. 如果在上面的步骤 1 和 2 中没有找到字段,并且 C 有一个超类 S,那么这个算法将在 S 上递归调用。如果 C 没有超类,那么将抛出 NoSuchFieldException。

    1. public class Test17 {
    2. public String name;
    3. public static void main(String[] args) throws NoSuchFieldException {
    4. System.out.println("Test17.class.getField(\"name\"): " + Test17.class.getField("name"));
    5. }
    6. }

    运行程序,输出:

    1. Test17.class.getField("name"): public java.lang.String test14.Test17.name

    getMethod

public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

getMethod 方法返回该实体的指定公共成员方法(public method)。参数 name 是一个字符串,指定所需方法的简单名称。parameterTypes 参数是一个 Class 对象数组,按声明的顺序标识方法的形式参数类型。如果 parameterTypes 为 null,则将其视为空数组。

  • 如果这个 Class 对象代表一个数组类型,则该方法返回 Object 类中除了 clone() 的指定公共方法;
  • 如果这个 Class 对象代表一个接口,则该方法不会返回 Object 类中的方法,因此,如果这个接口或者其任何父接口中没有声明该名称的方法,那么将抛出 NoSuchMethodException。

    1. public class Test18 {
    2. public static void main(String[] args) {
    3. try {
    4. System.out.println("List.class.getMethod(\"notify\"): " + List.class.getMethod("notify"));
    5. } catch (NoSuchMethodException e) {
    6. System.out.println("List.class.getMethod(\"notify\"): " + e.getClass());
    7. }
    8. try {
    9. System.out.println("int[].class.getMethod(\"notify\"): " + int[].class.getMethod("notify"));
    10. } catch (NoSuchMethodException e) {
    11. System.out.println("int[].class.getMethod(\"notify\"): " + e.getClass());
    12. }
    13. }
    14. }

    运行程序,输出:

    1. List.class.getMethod("notify"): class java.lang.NoSuchMethodException
    2. int[].class.getMethod("notify"): public final native void java.lang.Object.notify()

    getConstructor

public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

getConstructor 方法返回该实体的指定公共构造函数(public constructor)。parameterTypes 参数是一个 Class 对象数组,按声明的顺序标识构造函数的形式参数类型。

如果如果这个 Class 对象代表一个在非静态上下文中声明的内部类,parameterTypes 的第一个参数是外部类的 Class 对象。

  1. public class Test19 {
  2. class InnerClass {
  3. public InnerClass() {
  4. }
  5. }
  6. public static void main(String[] args) throws NoSuchMethodException {
  7. System.out.println("Test19.class.getConstructor(): " + Test19.class.getConstructor());
  8. System.out.println("InnerClass.class.getConstructor(Test19.class): " + InnerClass.class.getConstructor(Test19.class));
  9. }
  10. }

运行程序,输出:

  1. Test19.class.getConstructor(): public test14.Test19()
  2. InnerClass.class.getConstructor(Test19.class): public test14.Test19$InnerClass(test14.Test19)

getDeclaredClasses

public Class<?>[] getDeclaredClasses() throws SecurityException

getDeclaredClasses 方法返回该实体的所有成员类和成员接口,包括 public,protected,default 和 private 的类和接口,但不包括从父类继承的。

如果这个 Class 对象没有任何成员类和成员接口,或者这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。

  1. public class Test13 {
  2. public class MemberInnerClass3 {
  3. }
  4. }
  5. public class Test12 extends Test13 {
  6. public class MemberInnerClass {
  7. }
  8. private class MemberInnerClass2 {
  9. }
  10. public static class StaticInnerClass {
  11. }
  12. public static void main(String[] args) {
  13. class LocalClass {
  14. }
  15. Runnable runnable = new Runnable() {
  16. @Override
  17. public void run() {
  18. }
  19. };
  20. System.out.println("Test12.class.getDeclaredClasses(): " + Arrays.toString(Test12.class.getDeclaredClasses()));
  21. }
  22. }

运行程序,输出:

  1. Test12.class.getDeclaredClasses(): [class test14.Test12$StaticInnerClass, class test14.Test12$MemberInnerClass2, class test14.Test12$MemberInnerClass]

getDeclaredFields

public Field[] getDeclaredFields() throws SecurityException

getDeclaredFields 方法返回该实体声明的所有字段,包括 public,protected,default 和 private 字段,但不包括从父类继承的。

  • 如果这个 Class 对象代表一个没有声明字段的类或接口,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。

返回的数组中的元素没有被排序,也没有任何特定的顺序。

  1. public class Test14 {
  2. private String privateField;
  3. public String publicField;
  4. public static void main(String[] args) {
  5. System.out.println("Test14.class.getDeclaredFields(): " + Arrays.toString(Test14.class.getDeclaredFields()));
  6. }
  7. }

运行程序,输出:

  1. Test14.class.getDeclaredFields(): [private java.lang.String test14.Test14.privateField, public java.lang.String test14.Test14.publicField]

getDeclaredMethods

public Method[] getDeclaredMethods() throws SecurityException

getDeclaredMethods 方法返回该实体声明的所有方法,包括 public,protected,default 和 private 方法,但不包括从父类继承的。

  • 如果这个 Class 对象代表的类型有多个声明方法,这些方法具有相同的名称和参数类型,但有不同的返回类型,则返回的数组包含每一个方法的 Method 对象(存在这种情况么?);
  • 如果这个 Class 对象代表的类型有一个类的初始化方法 ,则返回的数组没有相应的 Method 对象(这是什么方法?);
  • 如果这个 Class 对象代表一个没有声明方法的类或接口,则该方法返回一个长度为 0 的数组;
  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。

返回的数组中的元素没有被排序,也没有任何特定的顺序。

  1. public class Test15 {
  2. public Test15() {
  3. }
  4. private void privateMethod() {
  5. }
  6. public void publicMethod() {
  7. }
  8. public static void staticMethod() {
  9. }
  10. public static void main(String[] args) {
  11. System.out.println("Test15.class.getDeclaredMethods(): " + Arrays.toString(Test15.class.getDeclaredMethods()));
  12. System.out.println("int[].class.getDeclaredMethods(): " + Arrays.toString(int[].class.getDeclaredMethods()));
  13. }
  14. }

运行程序,输出:

  1. Test15.class.getDeclaredMethods(): [public static void test14.Test15.main(java.lang.String[]), private void test14.Test15.privateMethod(), public static void test14.Test15.staticMethod(), public void test14.Test15.publicMethod()]
  2. int[].class.getDeclaredMethods(): []

getDeclaredConstructors

public Constructor<?>[] getDeclaredConstructors() throws SecurityException

getDeclaredConstructors 方法返回该实体(类)声明的所有构造函数,包括 public,protected,default 和 private 的构造函数,但不包括从父类继承的。

  • 如果这个 Class 对象代表的类有一个默认的构造函数,它将被包含在返回的数组中;
  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。

返回的数组中的元素没有被排序,也没有任何特定的顺序。

  1. public class Test16 {
  2. public static void main(String[] args) {
  3. System.out.println("Test16.class.getDeclaredConstructors(): " + Arrays.toString(Test16.class.getDeclaredConstructors()));
  4. System.out.println("int.class.getDeclaredConstructors(): " + Arrays.toString(int.class.getDeclaredConstructors()));
  5. System.out.println("String[].class.getDeclaredConstructors(): " + Arrays.toString(String[].class.getDeclaredConstructors()));
  6. }
  7. }

运行程序,输出:

  1. Test16.class.getDeclaredConstructors(): [public test14.Test16()]
  2. int.class.getDeclaredConstructors(): []
  3. String[].class.getDeclaredConstructors(): []

getDeclaredField

public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException

getDeclaredField 方法返回该实体声明的指定成员字段,包括 public,protected,default 和 private 字段,但不包括从父类继承的。参数 name 是一个字符串,指定所需字段的简单名称。

  1. public class Test17 {
  2. private String privateField;
  3. public String publicField;
  4. public static void main(String[] args) throws NoSuchFieldException {
  5. System.out.println("Test17.class.getDeclaredField(\"privateField\"): " + Test17.class.getDeclaredField("privateField"));
  6. }
  7. }

运行程序,输出:

  1. Test17.class.getDeclaredField("privateField"): private java.lang.String test14.Test17.privateField

getDeclaredMethod

public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

getDeclaredMethod 方法返回该实体声明的指定成员方法,包括 public,protected,default 和 private 方法,但不包括从父类继承的。

参数 name 是一个字符串,指定所需方法的简单名称。parameterTypes 参数是一个 Class 对象数组,按声明的顺序标识方法的形式参数类型。如果 parameterTypes 为 null,则将其视为空数组。

  1. public class Test18 {
  2. private void privateMethod() {
  3. }
  4. public void publicMethod() {
  5. }
  6. public static void main(String[] args) {
  7. try {
  8. System.out.println("Test18.class.getDeclaredMethod(\"privateMethod\"): " + Test18.class.getDeclaredMethod("privateMethod"));
  9. } catch (NoSuchMethodException e) {
  10. System.out.println("Test18.class.getDeclaredMethod(\"privateMethod\"): " + e.getClass());
  11. }
  12. }
  13. }

运行程序,输出:

  1. Test18.class.getDeclaredMethod("privateMethod"): private void test14.Test18.privateMethod()

getDeclaredConstructor

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException

getDeclaredConstructor 方法返回该实体(类)声明的指定构造函数,包括 public,protected,default 和 private 的构造函数,但不包括从父类继承的。parameterTypes 参数是一个 Class 对象数组,按声明的顺序标识构造函数的形式参数类型。

如果如果这个 Class 对象代表一个在非静态上下文中声明的内部类,parameterTypes 的第一个参数是外部类的 Class 对象。

  1. public class Test19 {
  2. class InnerClass {
  3. private InnerClass() {
  4. }
  5. }
  6. public static void main(String[] args) throws NoSuchMethodException {
  7. System.out.println("Test19.class.getDeclaredConstructor(): " + Test19.class.getDeclaredConstructor());
  8. System.out.println("InnerClass.class.getDeclaredConstructor(Test19.class): " + InnerClass.class.getDeclaredConstructor(Test19.class));
  9. }
  10. }

运行程序,输出:

  1. Test19.class.getDeclaredConstructor(): public test14.Test19()
  2. InnerClass.class.getDeclaredConstructor(Test19.class): private test14.Test19$InnerClass(test14.Test19)

getResourceAsStream

public InputStream getResourceAsStream(String name)

getResourceAsStream 方法返回指定名称的资源。

  • 如果这个 Class 对象代表的类是在一个命名的模块中,则此方法将尝试在模块中查找资源。这是通过委派给模块的类加载器 findResource(String,String) 方法来完成的,用模块名称和资源的绝对名称来调用它。命名模块中的资源受 Module getResourceAsStream 方法中指定的封装规则的约束,因此,当资源是一个非”.class “的资源,且不对调用者的模块开放时,该方法返回 null;
  • 如果如果这个 Class 对象代表的类不在一个命名的模块中,那么搜索与一个给定的类相关的资源的规则由该类的定义类加载器实现。这个方法委托给这个对象的类加载器。
  • 如果如果这个 Class 对象代表的类是由引导类加载器(bootstrap class loader)加载的,则该方法将委托给 ClassLoader.getSystemResourceAsStream。

资源路径有两种方式:

  1. 如果路径名称以 “/“ 开头,表示该路径是绝对路径,当然也不是磁盘的绝对路径,是从 ClassPath 根目录下获取资源;
  2. 如果路径名称不以”/“ 开头,表示从此类所在的包下获取资源。可以用 “.” 代表此类所在的包,用 “..” 代表此类所在包的上一层。

假设文件的目录结构如下所示:
image.png
Test1 类中想要获取 a.txt 文件,代码如下:

  1. public class Test1 {
  2. public static void main(String[] args) {
  3. System.out.println("Test1.class.getResourceAsStream(\"/test1/a.txt\"): " + Test1.class.getResourceAsStream("/test1/a.txt"));
  4. System.out.println("Test1.class.getResourceAsStream(\"../test1/a.txt\"): " + Test1.class.getResourceAsStream("../test1/a.txt"));
  5. }
  6. }

运行程序,输出:

  1. Test1.class.getResourceAsStream("/test1/a.txt"): java.io.BufferedInputStream@6ea12c19
  2. Test1.class.getResourceAsStream("../test1/a.txt"): java.io.BufferedInputStream@6a024a67

getResource

public URL getResource(String name)

getResourceAsStream 方法返回指定名称的资源 URL。其他描述和 getResourceAsStream 方法类似。

  1. public class Test1 {
  2. public static void main(String[] args) {
  3. System.out.println("Test1.class.getResource(\"/test1/a.txt\"): " + Test1.class.getResource("/test1/a.txt"));
  4. System.out.println("Test1.class.getResource(\"../test1/a.txt\"): " + Test1.class.getResource("../test1/a.txt"));
  5. }
  6. }

运行程序,输出:

  1. Test1.class.getResource("/test1/a.txt"): file:/E:/projects/test/target/classes/test1/a.txt
  2. Test1.class.getResource("../test1/a.txt"): file:/E:/projects/test/target/classes/test1/a.txt

getProtectionDomain

public java.security.ProtectionDomain getProtectionDomain()

getProtectionDomain 方法返回该实体的 ProtectionDomain。如果安装了一个安全管理器,这个方法首先调用安全管理器的 checkPermission 方法,用 RuntimePermission(“getProtectionDomain”) 权限来确保可以获得 ProtectionDomain。

isEnum

public boolean isEnum()

isEnum 方法判断该实体是否是一个枚举,如果是则返回 true,否则返回 false。

  1. public enum Color {
  2. RED, GREEN, BLANK, YELLOW;
  3. public static void main(String[] args) {
  4. System.out.println("Color.class.isEnum(): " + Color.class.isEnum());
  5. }
  6. }

运行程序,输出:

  1. Color.class.isEnum(): true

getEnumConstants

public T[] getEnumConstants()

getEnumConstants 方法返回该实体(枚举类)的元素。如果这个 Class 对象不代表一个枚举类型,则返回空。

  1. public enum Color {
  2. RED, GREEN, BLANK, YELLOW;
  3. public static void main(String[] args) {
  4. System.out.println("Color.class.getEnumConstants(): " + Arrays.toString(Color.class.getEnumConstants()));
  5. }
  6. }

运行程序,输出:

  1. Color.class.getEnumConstants(): [RED, GREEN, BLANK, YELLOW]

cast

public T cast(Object obj)

cast 方法将一个对象强转为这个 Class 对象所代表的类或接口。

asSubclass

public <U> Class<? extends U> asSubclass(Class<U> clazz)

asSubclass 方法将当前实体强转为指定类的一个子类。

在有些情况下,我们并不能确定一个 Class 对象的类型,典型的情况是 Class.forName() 获取的 Class 对象。

Class.forName() 的返回类型是 Class<?>,但这显然太宽泛了,假设我们需要 List 类型的 Class 对象,但我们传递给 Class.forName 的参数是未知的,可能是 “java.lang.String”,也可能是 “java.util.ArrayList”,这时我们就可以用到 asSubclass() 这个方法来缩小 Class<?> 的类型范围。

  1. Class.forName("xxx.xxx.xxx").asSubclass(List.class).newInstance();

如果 xxx.xxx.xxx 是 List 的子类时,则正常执行,如果不是 List 的子类时,则抛出 ClassCastException 异常,这时我们就可以做一些异常处理。

AnnotatedElement

AnnotatedElement 接口中定义了一系列操作注解的方法,Class 类实现了该接口。
image.png

getAnnotation

public <A extends Annotation> A getAnnotation(Class<A> annotationClass)

getAnnotation 方法返回该实体上声明的指定类型的注解,包括从父类和父接口继承的注解。如果该实体及其父类和父接口上没有声明指定类型的注解,则该方法返回 null。

getAnnotations

public Annotation[] getAnnotations()

getAnnotations 方法返回该实体上声明的所有注解,包括从父类和父接口继承的注解。如果该实体及其父类和父接口上没有声明注解,则该方法返回一个长度为 0 的数组。

getAnnotationsByType

public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass)

getAnnotationsByType 方法返回该实体上声明的指定类型的所有注解,包括从父类和父接口继承的注解。如果该实体及其父类和父接口上没有声明指定类型的注解,则该方法返回一个长度为 0 的数组。

该方法与 getAnnotation 的区别是,比如类上重复声明了注解 @subAnnotation,getAnnotation 方法返回 null,而 getAnnotationsByType 方法返回所有的注解 @subAnnotation

getDeclaredAnnotation

public <A extends Annotation> A getDeclaredAnnotation(Class<A> annotationClass)

getDeclaredAnnotation 方法返回该实体上声明的指定类型的注解,不包括从父类和父接口继承的注解。如果该实体上没有声明指定类型的注解,则该方法返回 null。

getDeclaredAnnotations

public Annotation[] getDeclaredAnnotations()

getDeclaredAnnotations 方法返回该实体上声明的所有注解,不包括从父类和父接口继承的注解。如果该实体没有声明注解,则该方法返回一个长度为 0 的数组。

getDeclaredAnnotationsByType

public <A extends Annotation> A[] getDeclaredAnnotationsByType(Class<A> annotationClass)

getDeclaredAnnotationsByType 方法返回该实体上声明的指定类型的所有注解,不包括从父类和父接口继承的注解。如果该实体上没有声明指定类型的注解,则该方法返回一个长度为 0 的数组。

该方法与 getDeclaredAnnotations 的区别是,比如类上重复声明了注解 @subAnnotation,getDeclaredAnnotations 方法返回 null,而 getDeclaredAnnotationsByType 方法返回所有的注解 @subAnnotation

isAnnotationPresent

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)

isAnnotationPresent 方法判断该实体上是否有指定类型的注解,包括从父类和父接口继承的注解。如果有则返回 true,否则返回 false。

如果想要父类的注解能够被子类继承,则该注解需要使用 @Inherited 修饰。

  1. @Inherited
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface SuperAnnotation {
  4. String message() default "";
  5. }
  6. @Retention(RetentionPolicy.RUNTIME)
  7. @Repeatable(SubAnnotation.List.class)
  8. public @interface SubAnnotation {
  9. String message() default "";
  10. @Retention(RUNTIME)
  11. @interface List {
  12. SubAnnotation[] value();
  13. }
  14. }
  15. @SuperAnnotation(message = "super annotation")
  16. public class SuperClass {
  17. }
  18. @SubAnnotation(message = "sub annotation 1")
  19. @SubAnnotation(message = "sub annotation 2")
  20. public class SubClass extends SuperClass {
  21. public static void main(String[] args) {
  22. System.out.println("SubClass.class.getAnnotation(SubAnnotation.class): " + SubClass.class.getAnnotation(SubAnnotation.class));
  23. System.out.println("SubClass.class.getAnnotation(SubAnnotation.List.class): " + SubClass.class.getAnnotation(SubAnnotation.List.class));
  24. System.out.println("SubClass.class.getAnnotation(SuperAnnotation.class): " + SubClass.class.getAnnotation(SuperAnnotation.class));
  25. System.out.println("SubClass.class.getDeclaredAnnotation(SubAnnotation.class): " + SubClass.class.getDeclaredAnnotation(SubAnnotation.class));
  26. System.out.println("SubClass.class.getDeclaredAnnotation(SubAnnotation.List.class): " + SubClass.class.getDeclaredAnnotation(SubAnnotation.List.class));
  27. System.out.println("SubClass.class.getDeclaredAnnotation(SuperAnnotation.class): " + SubClass.class.getDeclaredAnnotation(SuperAnnotation.class));
  28. System.out.println("SubClass.class.getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotations()));
  29. System.out.println("SubClass.class.getDeclaredAnnotations():" + Arrays.toString(SubClass.class.getDeclaredAnnotations()));
  30. System.out.println("SubClass.class.getAnnotationsByType(SubAnnotation.class)): " + Arrays.toString(SubClass.class.getAnnotationsByType(SubAnnotation.class)));
  31. System.out.println("SubClass.class.getDeclaredAnnotationsByType(SubAnnotation.class):" + Arrays.toString(SubClass.class.getDeclaredAnnotationsByType(SubAnnotation.class)));
  32. System.out.println("SubClass.class.isAnnotationPresent(SubAnnotation.class): " + SubClass.class.isAnnotationPresent(SubAnnotation.class));
  33. System.out.println("SubClass.class.isAnnotationPresent(SubAnnotation.List.class): " + SubClass.class.isAnnotationPresent(SubAnnotation.List.class));
  34. System.out.println("SubClass.class.isAnnotationPresent(SuperAnnotation.class): " + SubClass.class.isAnnotationPresent(SuperAnnotation.class));
  35. }
  36. }

运行程序,输出:

  1. SubClass.class.getAnnotation(SubAnnotation.class): null
  2. SubClass.class.getAnnotation(SubAnnotation.List.class): @test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})
  3. SubClass.class.getAnnotation(SuperAnnotation.class): @test15.SuperAnnotation(message="super annotation")
  4. SubClass.class.getDeclaredAnnotation(SubAnnotation.class): null
  5. SubClass.class.getDeclaredAnnotation(SubAnnotation.List.class): @test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})
  6. SubClass.class.getDeclaredAnnotation(SuperAnnotation.class): null
  7. SubClass.class.getAnnotations(): [@test15.SuperAnnotation(message="super annotation"), @test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})]
  8. SubClass.class.getDeclaredAnnotations():[@test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})]
  9. SubClass.class.getAnnotationsByType(SubAnnotation.class)): [@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")]
  10. SubClass.class.getDeclaredAnnotationsByType(SubAnnotation.class):[@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")]
  11. SubClass.class.isAnnotationPresent(SubAnnotation.class): false
  12. SubClass.class.isAnnotationPresent(SubAnnotation.List.class): true
  13. SubClass.class.isAnnotationPresent(SuperAnnotation.class): true

getAnnotatedSuperclass

public AnnotatedType getAnnotatedSuperclass()

getAnnotatedSuperclass 方法返回一个 AnnotatedType 对象,用于指向该实体的父类。

从 JDK 1.8 开始支持这个方法,服务于注解的新特性。

  1. @Inherited
  2. @Target({ElementType.TYPE_USE, ElementType.TYPE})
  3. @Retention(RetentionPolicy.RUNTIME)
  4. public @interface SuperAnnotation {
  5. String message() default "";
  6. }
  7. @SuperAnnotation(message = "super annotation 1")
  8. public class SuperClass {
  9. }
  10. public class SubClass extends @SuperAnnotation(message = "super annotation 2") SuperClass {
  11. public static void main(String[] args) {
  12. System.out.println("SubClass.class.getAnnotatedSuperclass().getType(): " + SubClass.class.getAnnotatedSuperclass().getType());
  13. System.out.println("SubClass.class.getAnnotatedSuperclass().getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedSuperclass().getAnnotations()));
  14. System.out.println("SubClass.class.getAnnotatedSuperclass().getDeclaredAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedSuperclass().getDeclaredAnnotations()));
  15. }
  16. }

运行程序,输出:

  1. SubClass.class.getAnnotatedSuperclass().getType(): class test15.SuperClass
  2. SubClass.class.getAnnotatedSuperclass().getAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]
  3. SubClass.class.getAnnotatedSuperclass().getDeclaredAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]

通过上面的例子,我们知道 getAnnotatedSuperclass 只支持 extends @SuperAnnotation(message = "super annotation 2") SuperClass 这种语法。

getAnnotatedInterfaces

public AnnotatedType[] getAnnotatedInterfaces()

getAnnotatedInterfaces 方法返回一个 AnnotatedType 对象的数组,用于指向该实体实现的接口。

从 JDK 1.8 开始支持这个方法,服务于注解的新特性。

  1. public class SubClass implements @SuperAnnotation(message = "super annotation 1") SuperInterface1, @SuperAnnotation(message = "super annotation 2") SuperInterface2 {
  2. public static void main(String[] args) {
  3. System.out.println("SubClass.class.getAnnotatedInterfaces()[0].getType(): " + SubClass.class.getAnnotatedInterfaces()[0].getType());
  4. System.out.println("SubClass.class.getAnnotatedInterfaces()[0].getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[0].getAnnotations()));
  5. System.out.println("SubClass.class.getAnnotatedInterfaces()[0].getDeclaredAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[0].getDeclaredAnnotations()));
  6. System.out.println("SubClass.class.getAnnotatedInterfaces()[1].getType(): " + SubClass.class.getAnnotatedInterfaces()[1].getType());
  7. System.out.println("SubClass.class.getAnnotatedInterfaces()[1].getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[1].getAnnotations()));
  8. System.out.println("SubClass.class.getAnnotatedInterfaces()[1].getDeclaredAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[1].getDeclaredAnnotations()));
  9. }
  10. }

运行程序,输出:

  1. SubClass.class.getAnnotatedInterfaces()[0].getType(): interface test15.SuperInterface1
  2. SubClass.class.getAnnotatedInterfaces()[0].getAnnotations(): [@test15.SuperAnnotation(message="super annotation 1")]
  3. SubClass.class.getAnnotatedInterfaces()[0].getDeclaredAnnotations(): [@test15.SuperAnnotation(message="super annotation 1")]
  4. SubClass.class.getAnnotatedInterfaces()[1].getType(): interface test15.SuperInterface2
  5. SubClass.class.getAnnotatedInterfaces()[1].getAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]
  6. SubClass.class.getAnnotatedInterfaces()[1].getDeclaredAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]

getNestHost

public Class<?> getNestHost()

getNestHost 方法返回该实体的外部类的 Class 对象,没有外部类则返回自身的 Class 对象。

  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回自身的 Class 对象;
  • 如果访问嵌套主机时出现链接错误,则该方法返回自身的 Class 对象。

从 JDK 11 开始支持这个方法。

isNestmateOf

public boolean isNestmateOf(Class<?> c)

isNestmateOf 方法判断该实体和指定的 Class 对象所代表的类或接口具有相同的外部类。

从 JDK 11 开始支持这个方法。

getNestMembers

public Class<?>[] getNestMembers()

getNestMembers 方法返回所有的类和接口,包括外部类、外部接口和嵌套类、嵌套接口。

  • 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回自身的 Class 对象;

从 JDK 11 开始支持这个方法。

  1. public class Melon {
  2. public class Slice {
  3. class Peeler {
  4. }
  5. }
  6. public class Juicer {
  7. }
  8. public static void main(String[] args) {
  9. Class<Melon> melonClass = Melon.class;
  10. Class<Melon.Slice> sliceClass = Melon.Slice.class;
  11. Class<Melon.Juicer> juicerClass = Melon.Juicer.class;
  12. Class<Melon.Slice.Peeler> peelerClass = Melon.Slice.Peeler.class;
  13. System.out.println("melonClass.getNestHost(): " + melonClass.getNestHost());
  14. System.out.println("sliceClass.getNestHost(): " + sliceClass.getNestHost());
  15. System.out.println("juicerClass.getNestHost(): " + juicerClass.getNestHost());
  16. System.out.println("peelerClass.getNestHost(): " + peelerClass.getNestHost());
  17. System.out.println("melonClass.getNestMembers(): " + Arrays.toString(melonClass.getNestMembers()));
  18. System.out.println("sliceClass.getNestMembers(): " + Arrays.toString(sliceClass.getNestMembers()));
  19. System.out.println("juicerClass.getNestMembers(): " + Arrays.toString(juicerClass.getNestMembers()));
  20. System.out.println("peelerClass.getNestMembers(): " + Arrays.toString(peelerClass.getNestMembers()));
  21. System.out.println("melonClass.isNestmateOf(sliceClass): " + melonClass.isNestmateOf(sliceClass));
  22. System.out.println("melonClass.isNestmateOf(juicerClass): " + melonClass.isNestmateOf(juicerClass));
  23. System.out.println("melonClass.isNestmateOf(peelerClass): " + melonClass.isNestmateOf(peelerClass));
  24. System.out.println("sliceClass.isNestmateOf(juicerClass): " + sliceClass.isNestmateOf(juicerClass));
  25. System.out.println("sliceClass.isNestmateOf(peelerClass): " + sliceClass.isNestmateOf(peelerClass));
  26. System.out.println("juicerClass.isNestmateOf(peelerClass): " + juicerClass.isNestmateOf(peelerClass));
  27. }
  28. }

运行程序,输出:

  1. melonClass.getNestHost(): class test15.Melon
  2. sliceClass.getNestHost(): class test15.Melon
  3. juicerClass.getNestHost(): class test15.Melon
  4. peelerClass.getNestHost(): class test15.Melon
  5. melonClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
  6. sliceClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
  7. juicerClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
  8. peelerClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
  9. melonClass.isNestmateOf(sliceClass): true
  10. melonClass.isNestmateOf(juicerClass): true
  11. melonClass.isNestmateOf(peelerClass): true
  12. sliceClass.isNestmateOf(juicerClass): true
  13. sliceClass.isNestmateOf(peelerClass): true
  14. juicerClass.isNestmateOf(peelerClass): true

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/lkv999 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。