检索类对象

所有反射操作的入口点是java.lang.Class。除了java.lang.reflect.ReflectPermissionjava.lang.reflect中的所有类都没有公共构造函数。要进入这些类,必须在Class上调用适当的方法。根据代码是否可以访问对象,类的名称,类型或现有的Class,有几种获取Class的方法。

Object.getClass()

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

Class c = "foo".getClass();

返回Class代表String

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

static方法System.console()返回与虚拟机关联的唯一控制台。 getClass()返回的值为与java.io.Console对应的Class

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

A是枚举E的实例;因此getClass()返回对应于枚举类型EClass

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.Set是类型java.util.HashSet的对象的interface。 getClass()返回的值是java.util.HashSet对应的类。

.class 语法

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

boolean b;
Class c = b.getClass();   // compile-time error

Class c = boolean.class;  // correct

请注意,语句_会产生编译时错误,因为boolean是原始类型并且无法取消引用。 .class语法返回与类型boolean对应的Class

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(即与double[].class相同)的数组相对应的ClasscStringArray变量将包含与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的情况下,才可以访问这些 API。

Class c = javax.swing.JButton.class.getSuperclass();

javax.swing.JButton的超类是javax.swing.AbstractButton

  • Class.getClasses()

    • 返回属于该类成员的所有公共类,interface和枚举,包括继承的成员。
Class<?>[] c = Character.class.getClasses();

Character包含两个成员类Character.SubsetCharacter.UnicodeBlock

Class<?>[] c = Character.class.getDeclaredClasses();

Character包含两个公共成员类Character.SubsetCharacter.UnicodeBlock和一个私有类Character.CharacterCache

import java.lang.reflect.Field;

Field f = System.class.getField("out");
Class c = f.getDeclaringClass();

out字段在System中声明。

public class MyClass {
    static Object o = new Object() {
        public void m() {} 
    };
    static Class<c> = o.getClass().getEnclosingClass();
}

o定义的匿名类的声明类为null

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包围。