1

使用反射可以在运行时检视Java类。检视类通常是使用反射时所做的第一件事情。从类中可以获得下面的信息。

  • 类名
  • 类修饰符(private、public、synchronized等)
  • 包信息
  • 超类
  • 所实现的接口
  • 构造函数
  • 方法
  • 属性
  • 注解

Java类中附加了很多信息,你可以在JavaDoc for java.lang.Class获得一个完整列表。本文将简要接触访问所有上述提到的信息。一些主题会在分章节中进行更详细的检查。例如,本文会展示如何获得所有的方法或者一个具体的方法,但分章节会展示如何调用那个方法、如何在名称相同的方法中匹配一个给定参数集合的方法、通过反射调用方法将抛出什么异常、如何发现一个get/set等。本文的主要目的是介绍Class对象和你通过它能获得的信息。

Class对象

对类做任何检视之前,必须先获得所检视类的java.lang.Class对象。包括所有原始类型(int、float、lang等)包括数组(arrays)等所有Java类型都拥有一个相关的Class对象。如果你知道类在编译时的名称,可以通过下面的代码获得它的Class对象:

Class myObjectClass = MyObject.class

如果你不知道类在编译时的名称,但知道类在运行时的名称字符串,可以参考下面的代码:

String className = ... //obtain class name as string at runtime
Class class = Class.forName(className);

当使用Class.forName()方法时,你必须提供类的全限定名。全限定名包含所有的包名。例如,如果MyObject位于包com.jenkov.myapp,那么它的全限定名是com.jenkov.myapp.MyObject
Class.forName() 方法在运行时classpath路径下找不到类时,会抛出一个ClassNotFoundException异常。

类名

Class对象包含两个版本的名称。全限定名(包含包名)使用getName()方法,如下:

Class aClass = ... //obtain Class object. See prev. section
String className = aClass.getName();

如果你需要获得不包含报名的类名称,你可以使用 getSimpleName()方法获得,如下:

Class  aClass          = ... //obtain Class object. See prev. section
String simpleClassName = aClass.getSimpleName();

修饰符

你可以通过Class对象访问一个类的修饰符。类修饰符关键字为publicprivate static等。获得类修饰符的代码如下:

Class  aClass = ... //obtain Class object. See prev. section
int modifiers = aClass.getModifiers();

修饰符被包装成int,每个修饰符都是一个标识位来标记设置或清除。你可以通过java.lang.reflect.Modifier类的下列方法检查修饰符:

Modifier.isAbstract(int modifiers)
Modifier.isFinal(int modifiers)
Modifier.isInterface(int modifiers)
Modifier.isNative(int modifiers)
Modifier.isPrivate(int modifiers)
Modifier.isProtected(int modifiers)
Modifier.isPublic(int modifiers)
Modifier.isStatic(int modifiers)
Modifier.isStrict(int modifiers)
Modifier.isSynchronized(int modifiers)
Modifier.isTransient(int modifiers)
Modifier.isVolatile(int modifiers)

包信息

你可以通过下面的方法获得包信息:

Class  aClass = ... //obtain Class object. See prev. section
Package package = aClass.getPackage();

你可以通过Package对象获取包信息,比如包名。你也可以访问位于classpath路径下的jar下的Manifest文件中的包的明确定义的包信息。例如,你可以在Manifest文件中指定包的版本号。你可以在 java.lang.Package中访问更详细的Package对象的信息。

超类

Class对象中你可以访问类的超类。代码如下:

Class superclass = aClass.getSuperclass();

超类对象也是一个普通的Class对象,所以你可以对它进行反射操作。

实现的接口

我们可以获得一个给定类的实现的接口的列表。代码如下:

Class  aClass = ... //obtain Class object. See prev. section
Class[] interfaces = aClass.getInterfaces();

一个类可以实现多个接口,因此返回值是一个Class数组。在反射中,接口也以Class对象表示。
注意:只有类显示实现的接口才返回。如果一个类的超类实现了一个接口,但是这个类没有实现,超类实现的接口不会包含在返回的数组中。即使这个类实际实现了那个接口(超类直接实现的接口),因为它是超类实现的。
如果需要获得一个类实现的完整接口列表,你必须递归这个类和它所有的超类。

构造函数

你可以访问类的构造函数,代码如下:

Constructor[] constructors = aClass.getConstructors();

构造函数的详细教程在Constructors章节。

方法

你可以访问类的方法,代码如下:

Method[] method = aClass.getMethods();

方法的更详尽教程在Methods章节。

属性

你可以访问类的属性(成员变量),代码如下:

Field[] method = aClass.getFields();

属性的更详尽教程在Fields章节。

注解

你可以访问一个类的注解,代码如下:

Annotation[] annotations = aClass.getAnnotations();

注解的更详尽教程在Annotations章节。


团结
128 声望8 粉丝

诗酒趁年华