使用反射可以在运行时检视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
对象访问一个类的修饰符。类修饰符关键字为public
、private
、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章节。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。