18.3. 2从Class中获取信息
Class
类提供了大量的实例方法来获取该Class
对象所对应类的详细信息, Class
类大致包含如下方法,下面每个方法都可能包括多个重载的版本,读者应该查阅API
文档来掌握它们。
获取构造器
下面4个方法用于获取Class
对应类所包含的构造器
方法 | 描述 |
---|---|
Constructor<T> getConstructor(Class<?>...parameter Types) |
返回此Class 对象对应类的、带指定形参列表的public 构造器。 |
Constructor<?>[] getConstructors() |
返回此 Class 对象对应类的所有public 构造器。 |
Constructor<T> getDeclaredConstructor( Class<?>...parameterTypes) |
返回此 Class 对象对应类的带指定形参列表的构造器,与构造器的访问权限无关。 |
Constructor<?>[] getDeclaredConstructors() |
返回此 Class 对象对应类的所有构造器,与构造器的访问权限无关。 |
获取方法
下面4个方法用于获取Class
对应类所包含的方法。
方法 | 描述 |
---|---|
Method getMethod(String name, Classs<?> ... parameterTypes) |
返回此Class 对象对应类的、带指定形参列表的 public 方法。 |
Method[] getMethods() |
返回此Class 对象所表示的类的所有 public 方法。 |
Method getDeclaredMethod(String name, Class<?> ... parameter Types) |
返回此 Class 对象对应类的、带指定形参列表的方法,与方法的访问权限无关。 |
Method[] getDeclaredMethods() |
返回此Class 对象对应类的全部方法,与方法的访问权限无关 |
获取成员变量
如下4个方法用于访问Class
对应类所包含的成员变量。
方法 | 描述 |
---|---|
Field getField(String name) |
返回此 Class 对象对应类的、指定名称的 public 成员变量。 |
Field[] getFields() |
返回此Class 对象对应类的所有 public 成员变量。 |
Field getDeclaredField(String name) |
返回此 Class 对象对应类的、指定名称的成员变量,与成员变量的访问权限无关。 |
Field[] getDeclaredFields() |
返回此 Class 对象对应类的全部成员变量,与成员变量的访问权限无关 |
获取Annotation
如下几个方法用于访问Class
对应类上所包含的Annotation
方法 | 描述 |
---|---|
<A extends Annotation> A getAnnotation(Class<A> annotationClass |
尝试获取该 Class 象对应类上存在的、指定类型的 Annotation ;如果该类型的注解不存在,则返回null 。 |
Annotation[] getAnnotations() |
返回修饰该 Class 对象对应类上存在的所有 Annotation |
<A extends annotation> A getDeclaredAnnotation(Class<A> annotationClass) |
这是Java 8 新增的方法,该方法尝试获取直接修饰该Class 对象对应类的、指定类型的Annotation ;如果该类型的注解不存在,则返回null 。 |
Annotation[] getDeclaredAnnotations() |
返回直接修饰该Class 对应类的所有 Annotation |
<A extends Annotation> A getAnnotationsByType(Class<A> annotationClass) |
该方法的功能与前面介绍的getAnnotation() 方法基本相似。但由于Java 8 增加了重复注解功能,因此需要使用该方法获取修饰该类的、指定类型的多个Annotation |
## 获取包含的内部类 ## | |
如下方法用于访问该Class 对象对应类包含的内部类。 |
方法 | 描述 |
---|---|
Class<?> getClasses() |
返回该Class 对象对应类里包含的全部内部类。 |
## 获取所在的外部类 ## | |
如下方法用于访问该Class 对象对应类所在的外部类。 |
方法 | 描述 |
---|---|
Class<?> getDeclaringClass() |
返回该Class 对象对应类所在的外部类 |
## 访问该Class对象对应类所实现的接口 ## | |
如下方法用于访问该Class 对象对应类所实现的接口 |
方法 | 描述 |
---|---|
Classs<?>[] getInterfaces() |
返回该Class 对象对应类所实现的全部接口。 |
## 获取所继承的父类 ## | |
如下几个方法用于访问该Class 对象对应类所继承的父类。 |
方法 | 描述 |
---|---|
Class<? super T> getSuperClass() |
返回该Class 对象对应类的超类的Class 对象。 |
## 获取修饰符 所在包 类名等基本信息 ## | |
如下方法用于获取Class 对象对应类的修饰符、所在包、类名等基本信息。 |
方法 | 描述 |
---|---|
int getModifiers() |
返回此类或接口的所有修饰符。修饰符由 public 、 protected 、 private 、final 、static 、 abstract 等对应的常量组成,返回的整数应使用 Modifier 工具类的方法来解码,才可以获取真实的修饰符。 |
Package getPackage() |
获取此类的包。 |
String getName() |
以字符串形式返回此Class 象所表示的类的名称。 |
String getSimpleName() |
以字符串形式返回此Class 对象所表示的类的简称。 |
## 判断该类是否为接口 枚举 注解类型 ## | |
除此之外, Class 对象还可调用如下几个判断方法来判断该类是否为接口、枚举、注解类型等。 |
方法 | 描述 |
---|---|
boolean isAnnotation() |
返回此Class 对象是否表示一个注解类型(由@interface 定义) |
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) |
判断此Class 对象是否使用了Annotation 修饰 |
boolean isAnonymousClass() |
返回此Class 对象是否是一个匿名类。 |
boolean isArray() |
返回此Class 对象是否表示一个数组类。 |
boolean isEnum() |
返回此Class 象是否表示一个枚举(由enum 关键字定义)。 |
boolean isInterface() |
返回此 Class 对象是否表示一个接口(使用 interface 定义)。 |
boolean isInstance(Object object) |
判断object 是否是此Class 对象的实例,该方法可以完全代替instanceof 操作符。 |
如何通过反射获取一个方法
上面的多个getMethod()
方法和getConstructor()
方法中,都需要传入多个类型为Classs<?>
的参数,用于获取指定的方法或指定的构造器。关于这个参数的作用,假设某个类内包含如下三个info
方法签名。
public void info()
public void info(String str)
public void info(String str,Integer num)
这三个同名方法属于重载
,它们的方法名相同,但参数列表不同
。在Java
语言中如果需要确定一个方法,则应该由方法名和形参列表来确定,但形参名没有任何实际意义
,所以只能由形参类型
来确定。例如想指定第二个info
方法,则必须指定:
- 方法名为
info
, - 形参列表为
String.class
因此在程序中获取该方法使用如下代码:
clazz.getMethod("info", String.class)
- 前一个参数指定方法名,后面的个数可变的
Class
参数指定形参类型列表。
- 前一个参数指定方法名,后面的个数可变的
如果需要获取第三个info
方法,则使用如下代码:
clazz.getMethod("info", String.class, Integer.class)
- 前一个参数指定方法名,后面的个数可变的
Class
参数指定形参类型列表。
- 前一个参数指定方法名,后面的个数可变的
如何通过反射获取一个构造器
获取构造器时无须传入构造器名—同一个类的所有构造器的名字都是相同的,所以要确定一个构造器只要指定形参列表即可。
程序示例
下面程序示范了如何通过该Class
对象来获取对应类的详细信息。
1 | import java.util.*; |
上面程序获取了ClassTest
类对应的Class
对象后,通过调用该Class
对象的不同方法来得到该Class
对象的详细信息。运行结果如下:
1 | ClassTest的全部构造器如下: |
从上面运行结果来看, Class
提供的功能非常丰富,它可以获取该类里包含的构造器
、方法
、内部类
、注解
等信息,也可以获取该类所包括的成员变量
(Field
)信息。
Class无法获取值显示在源代码上的注解
值得指出的是,虽然定义ClassTest
类时使用了 @SuppressWarnings
注解,但程序运行时无法分析出该类里包含的该注解,这是因为@SuppressWarnings
使用了@Retention(value= SOURCE)
修饰,这表明@SuppressWarnings
只能保存在源代码级别上,而通过ClassTest.class
取该类的运行时Class
对象,所以程序无法访问到@SuppressWarnings
注解。
对于只能在源代码上保留的注解,使用运行时获得的Class
对象无法访问到该注解对象。
通过Class
对象可以得到大量的Method
、 Constructor
、 Field
等对象,这些对象分别代表该类所包括的方法、构造器和成员变量等,程序还可以通过这些对象来执行实际的功能,例如调用方法、创建实例。
本文重点
通过Class
类,
- 可以获取对应类的构造器
- 可以获取对应类中方法
- 获取对应类的成员变量
- 获取对应类的
Annotation
- 获取对应类包含的内部类
- 获取对应类所在的外部类
- 获取对应类所实现的接口
- 获取对应类所继承的父类
- 获取对应类的修饰符 所在包 类名等基本信息
- 可以判断对应类是否为接口 枚举 注解类型
- 在获取方法时需要传入方法名和参数列表,
- 在获取构造器时只需要传入参数列表。
Class
无法获取值显示在源代码上的注解,例如@SuppressWarnings
注解无法通过反射获取
原文链接: 18.3.2 从Class中获取信息