文档

Java™ 教程-Java Tutorials 中文版
获取 Class 对象
Trail: The Reflection API
Lesson: Classes

获取 Class 对象

所有反射操作的入口点是 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();

有一个与虚拟机关联的唯一控制台,由 static 方法 System.console() 返回。getClass() 返回的值是对应于 java.io.ConsoleClass

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();   // compile-time error

Class c = boolean.class;  // correct

请注意,语句 boolean.getClass() 会产生编译时错误,因为 boolean 是基本类型,无法解除引用。.class 语法返回与 boolean 类型对应的 Class

Class c = java.io.PrintStream.class;

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

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,用于在需要 Object 时包装基本类型 doubleDouble.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()
返回声明了这些成员的 ClassAnonymous Class Declarations 不会有声明类,但会有一个封闭类。
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 封闭。

Previous page: Classes
Next page: Examining Class Modifiers and Types