- 前言
- 正文
- forName
- newInstance
- isInstance
- isAssignableFrom
- isInterface
- isArray
- isPrimitive
- isAnnotation
- isSynthetic
- getName
- getClassLoader
- getModule
- getTypeParameters
- getSuperclass
- getGenericSuperclass
- getPackage
- getPackageName
- getGenericInterfaces
- getComponentType
- getModifiers
- getSigners
- getEnclosingMethod
- getEnclosingConstructor
- getDeclaringClass
- getEnclosingClass
- getSimpleName
- getTypeName
- getCanonicalName
- isAnonymousClass
- isLocalClass
- isMemberClass
- getClasses
- getMethods
- getConstructors
- getField
- getMethod
- getConstructor
- getDeclaredClasses
- getDeclaredFields
- getDeclaredMethods
- getDeclaredConstructors
- getDeclaredField
- getDeclaredMethod
- getDeclaredConstructor
- getResourceAsStream
- getResource
- getProtectionDomain
- isEnum
- getEnumConstants
- cast
- asSubclass
- AnnotatedElement
- getAnnotatedSuperclass
- getAnnotatedInterfaces
- getNestHost
- isNestmateOf
- getNestMembers
前言
本文作为 Java 反射机制的一部分,整理了 Class 类中的所有方法,并给出了简单的使用案例作为参考。
版本约定
- JDK Version:11.0.12
- Java SE API Documentation:https://docs.oracle.com/en/java/javase/11/docs/api/index.html
正文
接下来列举的 Class 类提供的实例方法,默认情况下,指的都是对该 Class 对象所代表的实体(类、接口、数组类、原始类型或 void)的某些操作。
forName
forName 方法有三个重载方法。
public static Class<?> forName(String className) throws ClassNotFoundException
public static Class<?> forName(String name, boolean initialize, ClassLoader loader) throws ClassNotFoundException
public static Class<?> forName(Module module, String name)
forName 方法的使用在上面已经提到,就是返回与给定字符串名称的类或接口相关的类对象。
newInstance
@Deprecated(since="9") public T newInstance() throws InstantiationException, IllegalAccessException
newInstance 方法可以用来动态地创建一个类的实例。需要注意的是,它默认使用的是类的无参构造器,如果对应的类中没有提供无参构造器,会抛出异常。
例如,我想创建一个 Student 对象,除了调用 new Student() 这种方式,还可以使用 newlnstance 方法。
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
Class stuClass = Class.forName("test1.Student");
Student student = (Student) stuClass.newInstance();
}
如果想使用有参的构造器初始化对象,需要使用 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.
public static void main(String[] args) {
Class stuClass = Student.class;
Class objClass = Object.class;
Student student = new Student();
System.out.println("Student.class.isInstance(student): " + stuClass.isInstance(student));
System.out.println("Object.class.isInstance(student): " + objClass.isInstance(student));
System.out.println("Student.class.isInstance(null): " + stuClass.isInstance(null));
}
运行程序,输出:
Student.class.isInstance(student): true
Object.class.isInstance(student): true
Student.class.isInstance(null): false
isAssignableFrom
public boolean isAssignableFrom(Class<?> cls)
isAssignableFrom 方法判断该实体与指定的 Class 参数所表示的类或接口是否相同,或者是否是其超类或超接口。如果是则返回 true,否则返回 false。
如果这个 Class 对象代表一个基本类型,且指定的 Class 参数正是这个 Class 对象,则该方法返回 true,否则返回 false。
public static void main(String[] args) {
Class stuClass = Student.class;
Class objClass = Object.class;
Class intClass = int.class;
System.out.println("Object.class.isAssignableFrom(Object.class): " + objClass.isAssignableFrom(objClass));
System.out.println("Object.class.isAssignableFrom(Student.class): " + objClass.isAssignableFrom(stuClass));
System.out.println("Object.class.isAssignableFrom(int.class): " + objClass.isAssignableFrom(intClass));
System.out.println("int.class.isAssignableFrom(int.class): " + intClass.isAssignableFrom(int.class));
}
运行程序,输出:
Object.class.isAssignableFrom(Object.class): true
Object.class.isAssignableFrom(Student.class): true
Object.class.isAssignableFrom(int.class): false
int.class.isAssignableFrom(int.class): true
isInterface
public boolean isInterface()
isInterface 方法判断该实体是否是一个接口,如果是则返回 true,否则返回 false。
public static void main(String[] args) {
System.out.println("Map.class.isInterface(): " + Map.class.isInterface());
System.out.println("HashMap.class.isInterface(): " + HashMap.class.isInterface());
}
运行程序,输出:
Map.class.isInterface(): true
HashMap.class.isInterface(): false
isArray
public boolean isArray()
isArray 方法判断该实体是否是一个数组,如果是则返回 true,否则返回 false。
public static void main(String[] args) {
System.out.println("int[].class.isArray(): " + int[].class.isArray());
System.out.println("int.class.isArray(): " + int.class.isArray());
}
运行程序,输出:
int[].class.isArray(): true
int.class.isArray(): false
isPrimitive
public boolean isPrimitive()
isPrimitive 方法判断该实体是否是一个原始类型,如果是则返回 true,否则返回 false。Java 有 9 种原始类型:boolean,byte,char,short,int,long,float,double 和 void。
public static void main(String[] args) {
System.out.println("boolean.class.isPrimitive(): " + boolean.class.isPrimitive());
System.out.println("byte.class.isPrimitive(): " + byte.class.isPrimitive());
System.out.println("char.class.isPrimitive(): " + char.class.isPrimitive());
System.out.println("short.class.isPrimitive(): " + short.class.isPrimitive());
System.out.println("int.class.isPrimitive(): " + int.class.isPrimitive());
System.out.println("long.class.isPrimitive(): " + long.class.isPrimitive());
System.out.println("float.class.isPrimitive(): " + float.class.isPrimitive());
System.out.println("double.class.isPrimitive(): " + double.class.isPrimitive());
System.out.println("void.class.isPrimitive(): " + void.class.isPrimitive());
}
运行程序,输出:
boolean.class.isPrimitive(): true
byte.class.isPrimitive(): true
char.class.isPrimitive(): true
short.class.isPrimitive(): true
int.class.isPrimitive(): true
long.class.isPrimitive(): true
float.class.isPrimitive(): true
double.class.isPrimitive(): true
void.class.isPrimitive(): true
isAnnotation
public boolean isAnnotation()
isAnnotation 方法判断该实体是否是一个注解,如果是则返回 true,否则返回 false。需要注意的是,如果该方法返回 true,则 isInterface 方法也会返回 true,因为所有的注释类型都是接口。
public static void main(String[] args) {
System.out.println("Deprecated.class.isAnnotation(): " + Deprecated.class.isAnnotation());
System.out.println("Deprecated.class.isInterface(): " + Deprecated.class.isInterface());
}
运行程序,输出:
Deprecated.class.isAnnotation(): true
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 可以生成合成类。
public static void main(String[] args) {
Runnable r1 = new Runnable() {
@Override
public void run() {
}
};
Runnable r2 = () -> {
};
System.out.println("r1.isSynthetic(): " + r1.getClass().isSynthetic());
System.out.println("r2.isSynthetic(): " + r2.getClass().isSynthetic());
}
运行程序,输出:
r1.isSynthetic(): false
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 |
public static void main(String[] args) {
System.out.println("String.class.getName(): " + String.class.getName());
System.out.println("byte.class.getName(): " + byte.class.getName());
System.out.println("(new Object[3]).getClass().getName(): " + (new Object[3]).getClass().getName());
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());
}
运行程序,输出:
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
getClassLoader
public ClassLoader getClassLoader()
getClassLoader 方法返回加载该实体的类加载器。比如,new Student().getClass().getClassLoader()
返回加载 Student 类的类加载器。
如果一个类是通过 bootstrap class loader 加载的,通过这个方法获得 class loader 时,有些 JDK 的实现是会返回一个 null 的。另外,如果这个 Class 对象代表一个原始类型或 void,也会返回 null。
public static void main(String[] args) {
System.out.println("new Student().getClass().getClassLoader():" + new Student().getClass().getClassLoader());
System.out.println("int.class.getClassLoader(): " + int.class.getClassLoader());
System.out.println("void.class.getClassLoader(): " + void.class.getClassLoader());
}
运行程序,输出:
new Student().getClass().getClassLoader():jdk.internal.loader.ClassLoaders$AppClassLoader@2437c6dc
int.class.getClassLoader(): null
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 对象在一个未命名的模块中,则该方法将返回一个未命名模块。
运行程序,输出:public static void main(String[] args) {
System.out.println("int.class.getModule(): " + int.class.getModule());
System.out.println("new int[10].getClass().getModule(): " + new int[10].getClass().getModule());
System.out.println("Student.class.getModule(): " + Student.class.getModule());
}
int.class.getModule(): module java.base
new int[10].getClass().getModule(): module java.base
Student.class.getModule(): unnamed module @234bef66
getTypeParameters
public TypeVariable<Class<T>>[] getTypeParameters()
getTypeParameters 方法返回一个 TypeVariable 对象的数组,该数组代表由 GenericDeclaration 对象代表的泛型声明所声明的类型变量,按声明顺序排列。如果底层泛型声明没有声明任何类型变量,则返回一个长度为 0 的数组。
public static void main(String[] args) {
System.out.println("List.class.getTypeParameters(): " + Arrays.toString(List.class.getTypeParameters()));
System.out.println("Map.class.getTypeParameters(): " + Arrays.toString(Map.class.getTypeParameters()));
}
运行程序,输出:
List.class.getTypeParameters(): [E]
Map.class.getTypeParameters(): [K, V]
getSuperclass
public Class<? super T> getSuperclass()
getSuperclass 方法返回该实体的直接父类。
- 如果这个 Class 对象代表 Object 类,一个接口,一个原始类型,或者是 void,那则该方法返回 null;
- 如果这个 Class 对象代表一个数组类,则该方法返回 Object 类的 Class 对象。
运行程序,输出:public static void main(String[] args) {
System.out.println("ArrayList.class.getSuperclass(): " + ArrayList.class.getSuperclass());
System.out.println("Object.class.getSuperclass(): " + Object.class.getSuperclass());
System.out.println("List.class.getSuperclass(): " + List.class.getSuperclass());
System.out.println("int.class.getSuperclass(): " + int.class.getSuperclass());
System.out.println("void.class.getSuperclass(): " + void.class.getSuperclass());
System.out.println("int[].class.getSuperclass(): " + int[].class.getSuperclass());
}
ArrayList.class.getSuperclass(): class java.util.AbstractList
Object.class.getSuperclass(): null
List.class.getSuperclass(): null
int.class.getSuperclass(): null
void.class.getSuperclass(): null
int[].class.getSuperclass(): class java.lang.Object
getGenericSuperclass
public Type getGenericSuperclass()
getGenericSuperclass 方法返回该实体直接父类的 Type 对象。getGenericSuperclass 方法在 getSuperclass 方法的基础上,还可以获得直接父类的泛型参数的实际类型。
class CustomList extends ArrayList<String> {
}
public static void main(String[] args) {
System.out.println("ArrayList.class.getGenericSuperclass(): " + ArrayList.class.getGenericSuperclass());
System.out.println("Object.class.getGenericSuperclass(): " + Object.class.getGenericSuperclass());
System.out.println("List.class.getGenericSuperclass(): " + List.class.getGenericSuperclass());
System.out.println("int.class.getGenericSuperclass(): " + int.class.getGenericSuperclass());
System.out.println("void.class.getGenericSuperclass(): " + void.class.getGenericSuperclass());
System.out.println("int[].class.getGenericSuperclass(): " + int[].class.getGenericSuperclass());
System.out.println("CustomList.class.getGenericSuperclass(): " + CustomList.class.getGenericSuperclass());
}
运行程序,输出:
ArrayList.class.getGenericSuperclass(): java.util.AbstractList<E>
Object.class.getGenericSuperclass(): null
List.class.getGenericSuperclass(): null
int.class.getGenericSuperclass(): null
void.class.getGenericSuperclass(): null
int[].class.getGenericSuperclass(): class java.lang.Object
CustomList.class.getGenericSuperclass(): java.util.ArrayList<java.lang.String>
增加一个补充案例,获取泛型类中的泛型参数的实际类型。
class CustomMap extends HashMap<Integer, String> {}
public static void main(String[] args) {
Type genericSuperclass = CustomMap.class.getGenericSuperclass();
Type[] actualTypeArguments = ((ParameterizedType) genericSuperclass).getActualTypeArguments();
System.out.println("actualTypeArguments: " + Arrays.toString(actualTypeArguments));
}
运行程序,输出:
actualTypeArguments: [class java.lang.Integer, class java.lang.String]
getPackage
public Package getPackage()
getPackage 方法返回该实体的 Package 对象。如果这个 Class 代表一个数组类型,一个原始类型或 void,这个方法返回 null。
public static void main(String[] args) {
System.out.println("String.class.getPackage(): " + String.class.getPackage());
System.out.println("String[].class.getPackage(): " + String[].class.getPackage());
System.out.println("int.class.getPackage(): " + int.class.getPackage());
System.out.println("void.class.getPackage(): " + void.class.getPackage());
}
运行程序,输出:
String.class.getPackage(): package java.lang
String[].class.getPackage(): null
int.class.getPackage(): null
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()); }
运行程序,输出:
List.class.getPackageName(): java.util TestA.class.getPackageName(): test13 new TestB() {}.getClass().getPackageName(): test13 int.class.getPackageName(): java.lang String[].class.getPackageName(): java.lang
<a name="fNWLw"></a>
## getInterfaces
`public Class<?>[] getInterfaces()`
getInterfaces 方法返回该实体直接实现的接口。
- 如果这个 Class 对象代表一个类,则返回值是一个数组,它包含了该类所实现的所有接口。数组中接口的顺序与该类 implements 子句中的接口名顺序一致。例如,给定声明:
```java
class Shimmer implements FloorWax, DessertTopping { ... }
假设 s 的值为 Shimmer 的一个实例,表达式:
s.getClass().getInterfaces()[0];
的值为表示 FloorWax 接口的 Class 对象。
s.getClass().getInterfaces()[1];
的值为表示 DessertTopping 接口的 Class 对象。
- 如果这个 Class 对象代表一个接口,则该数组包含表示该接口扩展的所有接口的对象。数组中接口对象顺序与此对象所表示的接口的声明的 extends 子句中接口名顺序一致;
- 如果这个 Class 对象代表一个不实现任何接口的类或接口,则该方法返回一个长度为 0 的数组;
- 如果这个 Class 对象代表一个原始类型或 void,则该方法返回一个长度为 0 的数组;
- 如果这个 Class 对象代表一个数组类型,则该方法返回一个包含接口 Cloneable 和 java.io.Serializable 的数组。
运行程序,输出:public static void main(String[] args) {
System.out.println("ArrayList.class.getInterfaces(): " + Arrays.toString(ArrayList.class.getInterfaces()));
System.out.println("List.class.getInterfaces(): " + Arrays.toString(List.class.getInterfaces()));
System.out.println("Student.class.getInterfaces(): " + Arrays.toString(Student.class.getInterfaces()));
System.out.println("void.class.getInterfaces(): " + Arrays.toString(void.class.getInterfaces()));
System.out.println("int[].class.getInterfaces(): " + Arrays.toString(int[].class.getInterfaces()));
}
ArrayList.class.getInterfaces(): [interface java.util.List, interface java.util.RandomAccess, interface java.lang.Cloneable, interface java.io.Serializable]
List.class.getInterfaces(): [interface java.util.Collection]
Student.class.getInterfaces(): []
void.class.getInterfaces(): []
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 的数组。
运行程序,输出:public static void main(String[] args) {
System.out.println("ArrayList.class.getGenericInterfaces(): " + Arrays.toString(ArrayList.class.getGenericInterfaces()));
System.out.println("List.class.getGenericInterfaces(): " + Arrays.toString(List.class.getGenericInterfaces()));
System.out.println("Student.class.getGenericInterfaces(): " + Arrays.toString(Student.class.getGenericInterfaces()));
System.out.println("void.class.getGenericInterfaces(): " + Arrays.toString(void.class.getGenericInterfaces()));
System.out.println("int[].class.getGenericInterfaces(): " + Arrays.toString(int[].class.getGenericInterfaces()));
}
ArrayList.class.getGenericInterfaces(): [java.util.List<E>, interface java.util.RandomAccess, interface java.lang.Cloneable, interface java.io.Serializable]
List.class.getGenericInterfaces(): [java.util.Collection<E>]
Student.class.getGenericInterfaces(): []
void.class.getGenericInterfaces(): []
int[].class.getGenericInterfaces(): [interface java.lang.Cloneable, interface java.io.Serializable]
getComponentType
public Class<?> getComponentType()
- 如果这个 Class 对象代表一个数组类型,则该方法返回表示一个数组的组件类型的 Class。
- 如果这个 Class 对象不代表一个数组类型,则该方法返回 null。
运行程序,输出:public static void main(String[] args) {
System.out.println("int[].class.getComponentType(): " + int[].class.getComponentType());
System.out.println("String[].class.getComponentType(): " + String[].class.getComponentType());
System.out.println("List.class.getComponentType(): " + List.class.getComponentType());
}
int[].class.getComponentType(): int
String[].class.getComponentType(): class java.lang.String
List.class.getComponentType(): null
getModifiers
public int getModifiers()
getModifiers 方法返回该实体的 Java 语言修饰符,以整数形式编码。这些修饰符由 Java 虚拟机的 public、protected、private、final、static、abstract 和 interface 的常量组成,可以用 Modifier 类中的方法进行解码。
public static void main(String[] args) {
System.out.println("List.class.getModifiers(): " + List.class.getModifiers());
System.out.println("Modifier.toString(List.class.getModifiers()): " + Modifier.toString(List.class.getModifiers()));
}
运行程序,输出:
List.class.getModifiers(): 1537
Modifier.toString(List.class.getModifiers()): public abstract interface
getSigners
public Object[] getSigners()
getSigners 方法返回该实体的签名者。如果没有签名者,则返回 null。如果这个 Class 对象代表一个原始类型或 void,则该方法返回 null。
public static void main(String[] args) {
System.out.println("List.class.getSigners(): " + List.class.getSigners());
System.out.println("int.class.getSigners(): " + int.class.getSigners());
}
运行程序,输出:
List.class.getSigners(): null
int.class.getSigners(): null
getEnclosingMethod
public Method getEnclosingMethod() throws SecurityException
如果该实体代表一个局部内部类或匿名内部类,则 getEnclosingMethod 方法返回一个 Method 对象,该 Method 对象代表外部类创建该实体的方法。
如果该实体代表的局部内部类或匿名内部类不是通过方法创建,而是通过实例声明、实例初始化块、静态初始化块或构造函数创建,则该方法将返回 null。
public class Test25 {
private Runnable runnable1 = new Runnable() {
@Override
public void run() {
}
};
private Runnable runnable2;
{
runnable2 = new Runnable() {
@Override
public void run() {
}
};
}
private Runnable runnable3;
public Test25() {
runnable3 = new Runnable() {
@Override
public void run() {
}
};
}
private static Runnable runnable4 = new Runnable() {
@Override
public void run() {
}
};
private static Runnable runnable5;
static {
runnable5 = new Runnable() {
@Override
public void run() {
}
};
}
public Runnable getRunnable6() {
return new Runnable() {
@Override
public void run() {
}
};
}
public static void main(String[] args) {
Runnable runnable7 = new Runnable() {
@Override
public void run() {
}
};
Test25 test25 = new Test25();
System.out.println("runnable1.getClass().getEnclosingMethod(): " + test25.runnable1.getClass().getEnclosingMethod());
System.out.println("runnable2.getClass().getEnclosingMethod(): " + test25.runnable2.getClass().getEnclosingMethod());
System.out.println("runnable3.getClass().getEnclosingMethod(): " + test25.runnable3.getClass().getEnclosingMethod());
System.out.println("runnable4.getClass().getEnclosingMethod(): " + runnable4.getClass().getEnclosingMethod());
System.out.println("runnable5.getClass().getEnclosingMethod(): " + runnable5.getClass().getEnclosingMethod());
System.out.println("runnable6.getClass().getEnclosingMethod(): " + test25.getRunnable6().getClass().getEnclosingMethod());
System.out.println("runnable7.getClass().getEnclosingMethod(): " + runnable7.getClass().getEnclosingMethod());
}
}
运行程序,输出:
runnable1.getClass().getEnclosingMethod(): null
runnable2.getClass().getEnclosingMethod(): null
runnable3.getClass().getEnclosingMethod(): null
runnable4.getClass().getEnclosingMethod(): null
runnable5.getClass().getEnclosingMethod(): null
runnable6.getClass().getEnclosingMethod(): public java.lang.Runnable test13.Test25.getRunnable6()
runnable7.getClass().getEnclosingMethod(): public static void test13.Test25.main(java.lang.String[])
getEnclosingConstructor
public Constructor<?> getEnclosingConstructor() throws SecurityException
如果该实体代表一个局部内部类或匿名内部类,则 getEnclosingConstructor 方法返回一个 Constructor 对象,该 Constructor 对象代表外部类创建该实体的构造函数。
如果该实体代表的局部内部类或匿名内部类不是通过构造函数创建,而是通过实例声明、实例初始化块、静态初始化块或方法创建,则该方法将返回 null。
public class Test26 {
private Runnable runnable1 = new Runnable() {
@Override
public void run() {
}
};
private Runnable runnable2;
{
runnable2 = new Runnable() {
@Override
public void run() {
}
};
}
private Runnable runnable3;
public Test26() {
runnable3 = new Runnable() {
@Override
public void run() {
}
};
}
private static Runnable runnable4 = new Runnable() {
@Override
public void run() {
}
};
private static Runnable runnable5;
static {
runnable5 = new Runnable() {
@Override
public void run() {
}
};
}
public Runnable getRunnable6() {
return new Runnable() {
@Override
public void run() {
}
};
}
public static void main(String[] args) {
Runnable runnable7 = new Runnable() {
@Override
public void run() {
}
};
Test26 test26 = new Test26();
System.out.println("runnable1.getClass().getEnclosingConstructor(): " + test26.runnable1.getClass().getEnclosingConstructor());
System.out.println("runnable2.getClass().getEnclosingConstructor(): " + test26.runnable2.getClass().getEnclosingConstructor());
System.out.println("runnable3.getClass().getEnclosingConstructor(): " + test26.runnable3.getClass().getEnclosingConstructor());
System.out.println("runnable4.getClass().getEnclosingConstructor(): " + runnable4.getClass().getEnclosingConstructor());
System.out.println("runnable5.getClass().getEnclosingConstructor(): " + runnable5.getClass().getEnclosingConstructor());
System.out.println("runnable6.getClass().getEnclosingConstructor(): " + test26.getRunnable6().getClass().getEnclosingConstructor());
System.out.println("runnable7.getClass().getEnclosingConstructor(): " + runnable7.getClass().getEnclosingConstructor());
}
}
运行程序,输出:
runnable1.getClass().getEnclosingConstructor(): null
runnable2.getClass().getEnclosingConstructor(): null
runnable3.getClass().getEnclosingConstructor(): public test13.Test26()
runnable4.getClass().getEnclosingConstructor(): null
runnable5.getClass().getEnclosingConstructor(): null
runnable6.getClass().getEnclosingConstructor(): null
runnable7.getClass().getEnclosingConstructor(): null
getDeclaringClass
public Class<?> getDeclaringClass() throws SecurityException
- 如果这个 Class 对象所代表的类或接口是另一个类的成员,则该方法返回代表它被声明的类的 Class 对象;
- 如果这个类或接口不是任何其他类的成员,则该方法返回 null;
如果这个 Class 对象代表一个数组类型,一个原始类型,或者是 void,则该方法返回 null。
public class Test2 {
public class MemberInnerClass {
public class MemberInnerInnerClass {
}
}
public static class StaticInnerClass {
}
public static void main(String[] args) {
Runnable anonymousInnerClass = new Runnable() {
@Override
public void run() {
}
};
class LocalInnerClass {
}
System.out.println("MemberInnerClass.class.getDeclaringClass(): " + MemberInnerClass.class.getDeclaringClass());
System.out.println("MemberInnerClass.MemberInnerInnerClass.class.getDeclaringClass(): " + MemberInnerClass.MemberInnerInnerClass.class.getDeclaringClass());
System.out.println("StaticInnerClass.class.getDeclaringClass(): " + StaticInnerClass.class.getDeclaringClass());
System.out.println("anonymousInnerClass.getClass().getDeclaringClass(): " + anonymousInnerClass.getClass().getDeclaringClass());
System.out.println("LocalInnerClass.class.getDeclaringClass(): " + LocalInnerClass.class.getDeclaringClass());
}
}
运行程序,输出:
MemberInnerClass.class.getDeclaringClass(): class test14.Test2
MemberInnerClass.MemberInnerInnerClass.class.getDeclaringClass(): class test14.Test2$MemberInnerClass
StaticInnerClass.class.getDeclaringClass(): class test14.Test2
anonymousInnerClass.getClass().getDeclaringClass(): null
LocalInnerClass.class.getDeclaringClass(): null
getEnclosingClass
public Class<?> getEnclosingClass() throws SecurityException
getEnclosingClass 方法返回该实体的外部类的 Class 对象。和 getDeclaringClass 方法的功能类似,只是 getEnclosingClass 还可以获取匿名内部类和局部内部类的外部类的 Class 对象。
public class Test3 {
public class MemberInnerClass {
public class MemberInnerInnerClass {
}
}
public static class StaticInnerClass {
}
public static void main(String[] args) {
Runnable anonymousInnerClass = new Runnable() {
@Override
public void run() {
}
};
class LocalInnerClass {
}
System.out.println("MemberInnerClass.class.getEnclosingClass(): " + MemberInnerClass.class.getEnclosingClass());
System.out.println("MemberInnerClass.MemberInnerInnerClass.class.getEnclosingClass(): " + MemberInnerClass.MemberInnerInnerClass.class.getEnclosingClass());
System.out.println("StaticInnerClass.class.getEnclosingClass(): " + StaticInnerClass.class.getEnclosingClass());
System.out.println("anonymousInnerClass.getClass().getEnclosingClass(): " + anonymousInnerClass.getClass().getEnclosingClass());
System.out.println("LocalInnerClass.class.getEnclosingClass(): " + LocalInnerClass.class.getEnclosingClass());
}
}
运行程序,输出:
MemberInnerClass.class.getEnclosingClass(): class test14.Test3
MemberInnerClass.MemberInnerInnerClass.class.getEnclosingClass(): class test14.Test3$MemberInnerClass
StaticInnerClass.class.getEnclosingClass(): class test14.Test3
anonymousInnerClass.getClass().getEnclosingClass(): class test14.Test3
LocalInnerClass.class.getEnclosingClass(): class test14.Test3
getSimpleName
public String getSimpleName()
getSimpleName 方法返回该实体的简单名称。
- 如果这个 Class 对象代表一个匿名内部类,则返回一个空字符串;
- 如果这个 Class 对象代表一个数组类型,则返回一个带有 “[]” 的组件类型的简单名称,特别是,如果这个数组的组件类型是匿名的,则返回 “[]” 字符串。
运行程序,输出:public static void main(String[] args) {
System.out.println("List.class.getSimpleName(): " + List.class.getSimpleName());
System.out.println("int[].class.getSimpleName(): " + int[].class.getSimpleName());
}
List.class.getSimpleName(): List
int[].class.getSimpleName(): int[]
getTypeName
public String getTypeName()
getTypeName 方法返回该实体的类型名称。
- 如果这个 Class 对象代表一个数组类型,则返回一个带有 “[]” 的组件类型的类型名称;
- 如果这个 Class 对象不是代表数组类型,则返回 getName 方法获得的值。
运行程序,输出:public static void main(String[] args) {
System.out.println("int.class.getTypeName(): " + int.class.getTypeName());
System.out.println("List.class.getTypeName(): " + List.class.getTypeName());
System.out.println("int[].class.getTypeName(): " + int[].class.getTypeName());
System.out.println("String[].class.getTypeName(): " + String[].class.getTypeName());
}
int.class.getTypeName(): int
List.class.getTypeName(): java.util.List
int[].class.getTypeName(): int[]
String[].class.getTypeName(): java.lang.String[]
getCanonicalName
public String getCanonicalName()
getCanonicalName 方法返回该实体的 Java 语言规范定义的底层类的规范名称。如果这个 Class 对象代表一个本地类,或是一个匿名类,或是一个组件类型没有规范名称的数组,则返回 null。
public class Test7 {
public static void main(String[] args) {
class LocalClass {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("int.class.getCanonicalName(): " + int.class.getCanonicalName());
System.out.println("List.class.getCanonicalName(): " + List.class.getCanonicalName());
System.out.println("Student.class.getCanonicalName(): " + Student.class.getCanonicalName());
System.out.println("LocalClass.class.getCanonicalName(): " + LocalClass.class.getCanonicalName());
System.out.println("runnable.getClass().getCanonicalName(): " + runnable.getClass().getCanonicalName());
System.out.println("int[].class.getCanonicalName(): " + int[].class.getCanonicalName());
System.out.println("String[].class.getCanonicalName(): " + String[].class.getCanonicalName());
System.out.println("Student[].class.getCanonicalName(): " + Student[].class.getCanonicalName());
System.out.println("LocalClass[].class.getCanonicalName(): " + LocalClass[].class.getCanonicalName());
}
}
运行程序,输出:
int.class.getCanonicalName(): int
List.class.getCanonicalName(): java.util.List
Student.class.getCanonicalName(): test1.Student
LocalClass.class.getCanonicalName(): null
runnable.getClass().getCanonicalName(): null
int[].class.getCanonicalName(): int[]
String[].class.getCanonicalName(): java.lang.String[]
Student[].class.getCanonicalName(): test1.Student[]
LocalClass[].class.getCanonicalName(): null
isAnonymousClass
public boolean isAnonymousClass()
isAnonymousClass 方法判断该实体是否是一个匿名类,如果是则返回 true,否则返回 false。
public class Test8 {
public static void main(String[] args) {
class LocalClass {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("List.class.isAnonymousClass(): " + List.class.isAnonymousClass());
System.out.println("LocalClass.class.isAnonymousClass(): " + LocalClass.class.isAnonymousClass());
System.out.println("runnable.getClass().isAnonymousClass(): " + runnable.getClass().isAnonymousClass());
}
}
运行程序,输出:
List.class.isAnonymousClass(): false
LocalClass.class.isAnonymousClass(): false
runnable.getClass().isAnonymousClass(): true
isLocalClass
public boolean isLocalClass()
isLocalClass 方法判断该实体是否是一个本地类,如果是则返回 true,否则返回 false。
public class Test9 {
public static void main(String[] args) {
class LocalClass {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("List.class.isLocalClass(): " + List.class.isLocalClass());
System.out.println("LocalClass.class.isLocalClass(): " + LocalClass.class.isLocalClass());
System.out.println("runnable.getClass().isLocalClass(): " + runnable.getClass().isLocalClass());
}
}
运行程序,输出:
List.class.isLocalClass(): false
LocalClass.class.isLocalClass(): true
runnable.getClass().isLocalClass(): false
isMemberClass
public boolean isMemberClass()
isMemberClass 方法判断该实体是否是一个成员类,如果是则返回 true,否则返回 false。如果这个 Class 对象代表一个本地类,或是一个匿名类,则返回 false。
public class Test11 {
public class MemberInnerClass {
public class MemberInnerInnerClass {
}
}
public static class StaticInnerClass {
}
public static void main(String[] args) {
class LocalClass {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("MemberInnerClass.MemberInnerInnerClass.class.isMemberClass(): " + MemberInnerClass.MemberInnerInnerClass.class.isMemberClass());
System.out.println("MemberInnerClass.class.isMemberClass(): " + MemberInnerClass.class.isMemberClass());
System.out.println("StaticInnerClass.class.isMemberClass(): " + StaticInnerClass.class.isMemberClass());
System.out.println("LocalClass.class.isMemberClass(): " + LocalClass.class.isMemberClass());
System.out.println("runnable.getClass().isMemberClass(): " + runnable.getClass().isMemberClass());
}
}
运行程序,输出:
MemberInnerClass.MemberInnerInnerClass.class.isMemberClass(): true
MemberInnerClass.class.isMemberClass(): true
StaticInnerClass.class.isMemberClass(): true
LocalClass.class.isMemberClass(): false
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 {
public class MemberInnerClass {
}
private class MemberInnerClass2 {
}
public static class StaticInnerClass {
}
public static void main(String[] args) {
class LocalClass {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("Test12.class.getClasses(): " + Arrays.toString(Test12.class.getClasses()));
}
}
运行程序,输出:
Test12.class.getClasses(): [class test14.Test12$StaticInnerClass, class test14.Test12$MemberInnerClass, class test14.Test13$MemberInnerClass3]
<a name="pYbh1"></a>
## getFields
`public Field[] getFields() throws SecurityException`
getFields 方法返回该实体声明的所有公共字段(public field),包括从父类和父接口继承的公共字段,不返回私有字段(private field)。
- 如果这个 Class 对象代表一个没有可访问公共字段的类或接口,则该方法返回一个长度为 0 的数组;
- 如果这个 Class 对象代表一个类,则该方法返回这个类以及它的所有父类和父接口的公共字段;
- 如果这个 Class 对象代表一个接口,则该方法返回这个接口及其所有父接口的字段;
- 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。
返回的数组中的元素没有被排序,也没有任何特定的顺序。
```java
public class Test14 {
private String privateField;
public String publicField;
public static void main(String[] args) {
System.out.println("Test14.class.getFields(): " + Arrays.toString(Test14.class.getFields()));
}
}
运行程序,输出:
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() 的所有公共方法。
返回的数组中的元素没有被排序,也没有任何特定的顺序。
public class Test15 {
private void privateMethod() {
}
public void publicMethod() {
}
public static void main(String[] args) {
System.out.println("Test15.class.getMethods(): " + Arrays.toString(Test15.class.getMethods()));
System.out.println("int[].class.getMethods(): " + Arrays.toString(int[].class.getMethods()));
}
}
运行程序,输出:
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()]
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 的数组。
public class Test16 {
public Test16() {
}
public static void main(String[] args) {
System.out.println("Test16.class.getConstructors(): " + Arrays.toString(Test16.class.getConstructors()));
System.out.println("int.class.getConstructors(): " + Arrays.toString(int.class.getConstructors()));
System.out.println("String[].class.getConstructors(): " + Arrays.toString(String[].class.getConstructors()));
}
}
运行程序,输出:
Test16.class.getConstructors(): [public test14.Test16()]
int.class.getConstructors(): []
String[].class.getConstructors(): []
getField
public Field getField(String name) throws NoSuchFieldException, SecurityException
getField 方法返回该实体的指定公共成员字段(public field)。参数 name 是一个字符串,指定所需字段的简单名称。
返回的 Field 对象由以下算法确定。假设 C 是 Class 对象所表示的类或者接口:
- 如果 C 声明了该指定名称的公共字段,则返回该 Field 对象;
- 如果在上述步骤 1 中未找到任何字段,则将此算法递归应用于 C 的每个直接父接口,直接父接口按其声明的顺序进行搜索;
如果在上面的步骤 1 和 2 中没有找到字段,并且 C 有一个超类 S,那么这个算法将在 S 上递归调用。如果 C 没有超类,那么将抛出 NoSuchFieldException。
public class Test17 {
public String name;
public static void main(String[] args) throws NoSuchFieldException {
System.out.println("Test17.class.getField(\"name\"): " + Test17.class.getField("name"));
}
}
运行程序,输出:
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。
public class Test18 {
public static void main(String[] args) {
try {
System.out.println("List.class.getMethod(\"notify\"): " + List.class.getMethod("notify"));
} catch (NoSuchMethodException e) {
System.out.println("List.class.getMethod(\"notify\"): " + e.getClass());
}
try {
System.out.println("int[].class.getMethod(\"notify\"): " + int[].class.getMethod("notify"));
} catch (NoSuchMethodException e) {
System.out.println("int[].class.getMethod(\"notify\"): " + e.getClass());
}
}
}
运行程序,输出:
List.class.getMethod("notify"): class java.lang.NoSuchMethodException
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 对象。
public class Test19 {
class InnerClass {
public InnerClass() {
}
}
public static void main(String[] args) throws NoSuchMethodException {
System.out.println("Test19.class.getConstructor(): " + Test19.class.getConstructor());
System.out.println("InnerClass.class.getConstructor(Test19.class): " + InnerClass.class.getConstructor(Test19.class));
}
}
运行程序,输出:
Test19.class.getConstructor(): public test14.Test19()
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 的数组。
public class Test13 {
public class MemberInnerClass3 {
}
}
public class Test12 extends Test13 {
public class MemberInnerClass {
}
private class MemberInnerClass2 {
}
public static class StaticInnerClass {
}
public static void main(String[] args) {
class LocalClass {
}
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
System.out.println("Test12.class.getDeclaredClasses(): " + Arrays.toString(Test12.class.getDeclaredClasses()));
}
}
运行程序,输出:
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 的数组。
返回的数组中的元素没有被排序,也没有任何特定的顺序。
public class Test14 {
private String privateField;
public String publicField;
public static void main(String[] args) {
System.out.println("Test14.class.getDeclaredFields(): " + Arrays.toString(Test14.class.getDeclaredFields()));
}
}
运行程序,输出:
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 的数组。
返回的数组中的元素没有被排序,也没有任何特定的顺序。
public class Test15 {
public Test15() {
}
private void privateMethod() {
}
public void publicMethod() {
}
public static void staticMethod() {
}
public static void main(String[] args) {
System.out.println("Test15.class.getDeclaredMethods(): " + Arrays.toString(Test15.class.getDeclaredMethods()));
System.out.println("int[].class.getDeclaredMethods(): " + Arrays.toString(int[].class.getDeclaredMethods()));
}
}
运行程序,输出:
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()]
int[].class.getDeclaredMethods(): []
getDeclaredConstructors
public Constructor<?>[] getDeclaredConstructors() throws SecurityException
getDeclaredConstructors 方法返回该实体(类)声明的所有构造函数,包括 public,protected,default 和 private 的构造函数,但不包括从父类继承的。
- 如果这个 Class 对象代表的类有一个默认的构造函数,它将被包含在返回的数组中;
- 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回一个长度为 0 的数组。
返回的数组中的元素没有被排序,也没有任何特定的顺序。
public class Test16 {
public static void main(String[] args) {
System.out.println("Test16.class.getDeclaredConstructors(): " + Arrays.toString(Test16.class.getDeclaredConstructors()));
System.out.println("int.class.getDeclaredConstructors(): " + Arrays.toString(int.class.getDeclaredConstructors()));
System.out.println("String[].class.getDeclaredConstructors(): " + Arrays.toString(String[].class.getDeclaredConstructors()));
}
}
运行程序,输出:
Test16.class.getDeclaredConstructors(): [public test14.Test16()]
int.class.getDeclaredConstructors(): []
String[].class.getDeclaredConstructors(): []
getDeclaredField
public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException
getDeclaredField 方法返回该实体声明的指定成员字段,包括 public,protected,default 和 private 字段,但不包括从父类继承的。参数 name 是一个字符串,指定所需字段的简单名称。
public class Test17 {
private String privateField;
public String publicField;
public static void main(String[] args) throws NoSuchFieldException {
System.out.println("Test17.class.getDeclaredField(\"privateField\"): " + Test17.class.getDeclaredField("privateField"));
}
}
运行程序,输出:
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,则将其视为空数组。
public class Test18 {
private void privateMethod() {
}
public void publicMethod() {
}
public static void main(String[] args) {
try {
System.out.println("Test18.class.getDeclaredMethod(\"privateMethod\"): " + Test18.class.getDeclaredMethod("privateMethod"));
} catch (NoSuchMethodException e) {
System.out.println("Test18.class.getDeclaredMethod(\"privateMethod\"): " + e.getClass());
}
}
}
运行程序,输出:
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 对象。
public class Test19 {
class InnerClass {
private InnerClass() {
}
}
public static void main(String[] args) throws NoSuchMethodException {
System.out.println("Test19.class.getDeclaredConstructor(): " + Test19.class.getDeclaredConstructor());
System.out.println("InnerClass.class.getDeclaredConstructor(Test19.class): " + InnerClass.class.getDeclaredConstructor(Test19.class));
}
}
运行程序,输出:
Test19.class.getDeclaredConstructor(): public test14.Test19()
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。
资源路径有两种方式:
- 如果路径名称以 “/“ 开头,表示该路径是绝对路径,当然也不是磁盘的绝对路径,是从 ClassPath 根目录下获取资源;
- 如果路径名称不以”/“ 开头,表示从此类所在的包下获取资源。可以用 “.” 代表此类所在的包,用 “..” 代表此类所在包的上一层。
假设文件的目录结构如下所示:
Test1 类中想要获取 a.txt 文件,代码如下:
public class Test1 {
public static void main(String[] args) {
System.out.println("Test1.class.getResourceAsStream(\"/test1/a.txt\"): " + Test1.class.getResourceAsStream("/test1/a.txt"));
System.out.println("Test1.class.getResourceAsStream(\"../test1/a.txt\"): " + Test1.class.getResourceAsStream("../test1/a.txt"));
}
}
运行程序,输出:
Test1.class.getResourceAsStream("/test1/a.txt"): java.io.BufferedInputStream@6ea12c19
Test1.class.getResourceAsStream("../test1/a.txt"): java.io.BufferedInputStream@6a024a67
getResource
public URL getResource(String name)
getResourceAsStream 方法返回指定名称的资源 URL。其他描述和 getResourceAsStream 方法类似。
public class Test1 {
public static void main(String[] args) {
System.out.println("Test1.class.getResource(\"/test1/a.txt\"): " + Test1.class.getResource("/test1/a.txt"));
System.out.println("Test1.class.getResource(\"../test1/a.txt\"): " + Test1.class.getResource("../test1/a.txt"));
}
}
运行程序,输出:
Test1.class.getResource("/test1/a.txt"): file:/E:/projects/test/target/classes/test1/a.txt
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。
public enum Color {
RED, GREEN, BLANK, YELLOW;
public static void main(String[] args) {
System.out.println("Color.class.isEnum(): " + Color.class.isEnum());
}
}
运行程序,输出:
Color.class.isEnum(): true
getEnumConstants
public T[] getEnumConstants()
getEnumConstants 方法返回该实体(枚举类)的元素。如果这个 Class 对象不代表一个枚举类型,则返回空。
public enum Color {
RED, GREEN, BLANK, YELLOW;
public static void main(String[] args) {
System.out.println("Color.class.getEnumConstants(): " + Arrays.toString(Color.class.getEnumConstants()));
}
}
运行程序,输出:
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<?> 的类型范围。
Class.forName("xxx.xxx.xxx").asSubclass(List.class).newInstance();
如果 xxx.xxx.xxx 是 List 的子类时,则正常执行,如果不是 List 的子类时,则抛出 ClassCastException 异常,这时我们就可以做一些异常处理。
AnnotatedElement
AnnotatedElement 接口中定义了一系列操作注解的方法,Class 类实现了该接口。
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
修饰。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface SuperAnnotation {
String message() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(SubAnnotation.List.class)
public @interface SubAnnotation {
String message() default "";
@Retention(RUNTIME)
@interface List {
SubAnnotation[] value();
}
}
@SuperAnnotation(message = "super annotation")
public class SuperClass {
}
@SubAnnotation(message = "sub annotation 1")
@SubAnnotation(message = "sub annotation 2")
public class SubClass extends SuperClass {
public static void main(String[] args) {
System.out.println("SubClass.class.getAnnotation(SubAnnotation.class): " + SubClass.class.getAnnotation(SubAnnotation.class));
System.out.println("SubClass.class.getAnnotation(SubAnnotation.List.class): " + SubClass.class.getAnnotation(SubAnnotation.List.class));
System.out.println("SubClass.class.getAnnotation(SuperAnnotation.class): " + SubClass.class.getAnnotation(SuperAnnotation.class));
System.out.println("SubClass.class.getDeclaredAnnotation(SubAnnotation.class): " + SubClass.class.getDeclaredAnnotation(SubAnnotation.class));
System.out.println("SubClass.class.getDeclaredAnnotation(SubAnnotation.List.class): " + SubClass.class.getDeclaredAnnotation(SubAnnotation.List.class));
System.out.println("SubClass.class.getDeclaredAnnotation(SuperAnnotation.class): " + SubClass.class.getDeclaredAnnotation(SuperAnnotation.class));
System.out.println("SubClass.class.getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotations()));
System.out.println("SubClass.class.getDeclaredAnnotations():" + Arrays.toString(SubClass.class.getDeclaredAnnotations()));
System.out.println("SubClass.class.getAnnotationsByType(SubAnnotation.class)): " + Arrays.toString(SubClass.class.getAnnotationsByType(SubAnnotation.class)));
System.out.println("SubClass.class.getDeclaredAnnotationsByType(SubAnnotation.class):" + Arrays.toString(SubClass.class.getDeclaredAnnotationsByType(SubAnnotation.class)));
System.out.println("SubClass.class.isAnnotationPresent(SubAnnotation.class): " + SubClass.class.isAnnotationPresent(SubAnnotation.class));
System.out.println("SubClass.class.isAnnotationPresent(SubAnnotation.List.class): " + SubClass.class.isAnnotationPresent(SubAnnotation.List.class));
System.out.println("SubClass.class.isAnnotationPresent(SuperAnnotation.class): " + SubClass.class.isAnnotationPresent(SuperAnnotation.class));
}
}
运行程序,输出:
SubClass.class.getAnnotation(SubAnnotation.class): null
SubClass.class.getAnnotation(SubAnnotation.List.class): @test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})
SubClass.class.getAnnotation(SuperAnnotation.class): @test15.SuperAnnotation(message="super annotation")
SubClass.class.getDeclaredAnnotation(SubAnnotation.class): null
SubClass.class.getDeclaredAnnotation(SubAnnotation.List.class): @test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})
SubClass.class.getDeclaredAnnotation(SuperAnnotation.class): null
SubClass.class.getAnnotations(): [@test15.SuperAnnotation(message="super annotation"), @test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})]
SubClass.class.getDeclaredAnnotations():[@test15.SubAnnotation$List(value={@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")})]
SubClass.class.getAnnotationsByType(SubAnnotation.class)): [@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")]
SubClass.class.getDeclaredAnnotationsByType(SubAnnotation.class):[@test15.SubAnnotation(message="sub annotation 1"), @test15.SubAnnotation(message="sub annotation 2")]
SubClass.class.isAnnotationPresent(SubAnnotation.class): false
SubClass.class.isAnnotationPresent(SubAnnotation.List.class): true
SubClass.class.isAnnotationPresent(SuperAnnotation.class): true
getAnnotatedSuperclass
public AnnotatedType getAnnotatedSuperclass()
getAnnotatedSuperclass 方法返回一个 AnnotatedType 对象,用于指向该实体的父类。
从 JDK 1.8 开始支持这个方法,服务于注解的新特性。
@Inherited
@Target({ElementType.TYPE_USE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SuperAnnotation {
String message() default "";
}
@SuperAnnotation(message = "super annotation 1")
public class SuperClass {
}
public class SubClass extends @SuperAnnotation(message = "super annotation 2") SuperClass {
public static void main(String[] args) {
System.out.println("SubClass.class.getAnnotatedSuperclass().getType(): " + SubClass.class.getAnnotatedSuperclass().getType());
System.out.println("SubClass.class.getAnnotatedSuperclass().getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedSuperclass().getAnnotations()));
System.out.println("SubClass.class.getAnnotatedSuperclass().getDeclaredAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedSuperclass().getDeclaredAnnotations()));
}
}
运行程序,输出:
SubClass.class.getAnnotatedSuperclass().getType(): class test15.SuperClass
SubClass.class.getAnnotatedSuperclass().getAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]
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 开始支持这个方法,服务于注解的新特性。
public class SubClass implements @SuperAnnotation(message = "super annotation 1") SuperInterface1, @SuperAnnotation(message = "super annotation 2") SuperInterface2 {
public static void main(String[] args) {
System.out.println("SubClass.class.getAnnotatedInterfaces()[0].getType(): " + SubClass.class.getAnnotatedInterfaces()[0].getType());
System.out.println("SubClass.class.getAnnotatedInterfaces()[0].getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[0].getAnnotations()));
System.out.println("SubClass.class.getAnnotatedInterfaces()[0].getDeclaredAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[0].getDeclaredAnnotations()));
System.out.println("SubClass.class.getAnnotatedInterfaces()[1].getType(): " + SubClass.class.getAnnotatedInterfaces()[1].getType());
System.out.println("SubClass.class.getAnnotatedInterfaces()[1].getAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[1].getAnnotations()));
System.out.println("SubClass.class.getAnnotatedInterfaces()[1].getDeclaredAnnotations(): " + Arrays.toString(SubClass.class.getAnnotatedInterfaces()[1].getDeclaredAnnotations()));
}
}
运行程序,输出:
SubClass.class.getAnnotatedInterfaces()[0].getType(): interface test15.SuperInterface1
SubClass.class.getAnnotatedInterfaces()[0].getAnnotations(): [@test15.SuperAnnotation(message="super annotation 1")]
SubClass.class.getAnnotatedInterfaces()[0].getDeclaredAnnotations(): [@test15.SuperAnnotation(message="super annotation 1")]
SubClass.class.getAnnotatedInterfaces()[1].getType(): interface test15.SuperInterface2
SubClass.class.getAnnotatedInterfaces()[1].getAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]
SubClass.class.getAnnotatedInterfaces()[1].getDeclaredAnnotations(): [@test15.SuperAnnotation(message="super annotation 2")]
getNestHost
public Class<?> getNestHost()
getNestHost 方法返回该实体的外部类的 Class 对象,没有外部类则返回自身的 Class 对象。
- 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回自身的 Class 对象;
- 如果访问嵌套主机时出现链接错误,则该方法返回自身的 Class 对象。
isNestmateOf
public boolean isNestmateOf(Class<?> c)
isNestmateOf 方法判断该实体和指定的 Class 对象所代表的类或接口具有相同的外部类。
getNestMembers
public Class<?>[] getNestMembers()
getNestMembers 方法返回所有的类和接口,包括外部类、外部接口和嵌套类、嵌套接口。
- 如果这个 Class 对象代表一个原始类型,一个数组类型,或者是 void,则该方法返回自身的 Class 对象;
从 JDK 11 开始支持这个方法。
public class Melon {
public class Slice {
class Peeler {
}
}
public class Juicer {
}
public static void main(String[] args) {
Class<Melon> melonClass = Melon.class;
Class<Melon.Slice> sliceClass = Melon.Slice.class;
Class<Melon.Juicer> juicerClass = Melon.Juicer.class;
Class<Melon.Slice.Peeler> peelerClass = Melon.Slice.Peeler.class;
System.out.println("melonClass.getNestHost(): " + melonClass.getNestHost());
System.out.println("sliceClass.getNestHost(): " + sliceClass.getNestHost());
System.out.println("juicerClass.getNestHost(): " + juicerClass.getNestHost());
System.out.println("peelerClass.getNestHost(): " + peelerClass.getNestHost());
System.out.println("melonClass.getNestMembers(): " + Arrays.toString(melonClass.getNestMembers()));
System.out.println("sliceClass.getNestMembers(): " + Arrays.toString(sliceClass.getNestMembers()));
System.out.println("juicerClass.getNestMembers(): " + Arrays.toString(juicerClass.getNestMembers()));
System.out.println("peelerClass.getNestMembers(): " + Arrays.toString(peelerClass.getNestMembers()));
System.out.println("melonClass.isNestmateOf(sliceClass): " + melonClass.isNestmateOf(sliceClass));
System.out.println("melonClass.isNestmateOf(juicerClass): " + melonClass.isNestmateOf(juicerClass));
System.out.println("melonClass.isNestmateOf(peelerClass): " + melonClass.isNestmateOf(peelerClass));
System.out.println("sliceClass.isNestmateOf(juicerClass): " + sliceClass.isNestmateOf(juicerClass));
System.out.println("sliceClass.isNestmateOf(peelerClass): " + sliceClass.isNestmateOf(peelerClass));
System.out.println("juicerClass.isNestmateOf(peelerClass): " + juicerClass.isNestmateOf(peelerClass));
}
}
运行程序,输出:
melonClass.getNestHost(): class test15.Melon
sliceClass.getNestHost(): class test15.Melon
juicerClass.getNestHost(): class test15.Melon
peelerClass.getNestHost(): class test15.Melon
melonClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
sliceClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
juicerClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
peelerClass.getNestMembers(): [class test15.Melon, class test15.Melon$Juicer, class test15.Melon$Slice, class test15.Melon$Slice$Peeler]
melonClass.isNestmateOf(sliceClass): true
melonClass.isNestmateOf(juicerClass): true
melonClass.isNestmateOf(peelerClass): true
sliceClass.isNestmateOf(juicerClass): true
sliceClass.isNestmateOf(peelerClass): true
juicerClass.isNestmateOf(peelerClass): true
作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/lkv999 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。