文档

Java™教程
隐藏目录
检索类对象
导航: 反射API
课程:

检索类对象

所有反射操作的入口点是java.lang.Class。除了java.lang.reflect.ReflectPermission之外,java.lang.reflect中的其他类都没有公共构造函数。要访问这些类,需要在Class上调用适当的方法。可以通过对象实例、类名、类型或现有的Class来获取Class

Object.getClass()

如果有一个对象的实例可用,那么最简单的获取其Class的方法是调用Object.getClass()。当然,这只适用于继承自Object的引用类型。以下是一些示例。

Class c = "foo".getClass();

返回StringClass

Class c = System.console().getClass();

虚拟机关联了一个唯一的控制台,可以通过静态方法System.console()返回。由getClass()返回的值是与java.io.Console对应的Class

enum E { A, B }
Class c = A.getClass();

A是枚举类型E的一个实例;因此,getClass()返回与枚举类型E相对应的Class

byte[] bytes = new byte[1024];
Class c = bytes.getClass();

由于数组是Objects,因此也可以在数组的实例上调用getClass()。返回的Class对应于具有组件类型byte的数组。

import java.util.HashSet;
import java.util.Set;

Set<String> s = new HashSet<String>();
Class c = s.getClass();

在这种情况下,java.util.Setjava.util.HashSet类型的对象的接口。由getClass()返回的值是对应于java.util.HashSet的类。

.class语法

如果类型是可用的但没有实例,则可以通过将".class"附加到类型的名称来获取Class。这也是获取原始类型的Class的最简单方法。

boolean b;
Class c = b.getClass();   // 编译时错误

Class c = boolean.class;  // 正确

请注意,语句boolean.getClass()会产生编译时错误,因为boolean是原始类型,不能被引用。而.class语法返回对应于类型booleanClass

Class c = java.io.PrintStream.class;

变量c将是与类型java.io.PrintStream对应的Class

Class c = int[][][].class;

使用.class语法可以获取给定类型的多维数组对应的Class

Class.forName()

如果类的全限定名可用,可以使用静态方法Class.forName()来获取相应的Class。但是这不能用于基本类型。数组类的名称语法由Class.getName()描述。这个语法适用于引用类型和基本类型。

Class c = Class.forName("com.duke.MyLocaleServiceProvider");

这个语句将根据给定的全限定名创建一个类。

Class cDoubleArray = Class.forName("[D");

Class cStringArray = Class.forName("[[Ljava.lang.String;");

变量cDoubleArray将包含与基本类型double的数组对应的Class(与double[].class相同)。变量cStringArray将包含与二维数组String对应的Class(与String[][].class相同)。

原始类型包装类的TYPE字段

.class语法是获取原始类型的Class的更方便和首选方式;然而,还有另一种获取Class的方法。每个原始类型和voidjava.lang中都有一个包装类,用于将原始类型装箱为引用类型。每个包装类都包含一个名为TYPE的字段,该字段等于被包装的原始类型的Class

Class c = Double.TYPE;

有一个类java.lang.Double,用于封装基本类型double,当需要一个Object时使用。 Double.TYPE的值与double.class相同。

Class c = Void.TYPE;

Void.TYPEvoid.class相同。

返回类的方法

有几个反射API返回类,但只有在已经直接或间接地获取到Class的情况下才能访问。

Class.getSuperclass()
返回给定类的父类。
Class c = javax.swing.JButton.class.getSuperclass();
javax.swing.JButton的父类是javax.swing.AbstractButton
Class.getClasses()
返回该类的所有公共类、接口和枚举,包括继承的成员。
Class<?>[] c = Character.class.getClasses();
Character包含两个成员类Character.SubsetCharacter.UnicodeBlock
Class.getDeclaredClasses()
返回在该类中显式声明的所有类、接口和枚举。
Class<?>[] c = Character.class.getDeclaredClasses();
Character包含两个公共成员类Character.SubsetCharacter.UnicodeBlock,以及一个私有类Character.CharacterCache
Class.getDeclaringClass()
java.lang.reflect.Field.getDeclaringClass()
java.lang.reflect.Method.getDeclaringClass()
java.lang.reflect.Constructor.getDeclaringClass()
返回声明这些成员的Class。匿名类声明没有声明的类,但有一个封闭的类。
import java.lang.reflect.Field;

Field f = System.class.getField("out");
Class c = f.getDeclaringClass();
字段outSystem中声明。
public class MyClass {
    static Object o = new Object() {
        public void m() {} 
    };
    static Class<c> = o.getClass().getEnclosingClass();
}
o定义的匿名类的声明类为null
Class.getEnclosingClass()
返回类的直接封闭类。
Class c = Thread.State.class().getEnclosingClass();
枚举Thread.State的封闭类为Thread
public class MyClass {
    static Object o = new Object() { 
        public void m() {} 
    };
    static Class<c> = o.getClass().getEnclosingClass();
}
o定义的匿名类被MyClass封闭。

上一页:
下一页:检查类的修饰符和类型