检索类对象
所有反射操作的入口点是java.lang.Class。除了java.lang.reflect.ReflectPermission,java.lang.reflect中的所有类都没有公共构造函数。要进入这些类,必须在Class上调用适当的方法。根据代码是否可以访问对象,类的名称,类型或现有的Class,有几种获取Class的方法。
Object.getClass()
如果对象的实例可用,则获取其Class的最简单方法是调用Object.getClass()。当然,这仅适用于都继承自Object的引用类型。以下是一些示例。
Class c = "foo".getClass();
Class c = System.console().getClass();
static
方法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.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
相同)的数组相对应的Class。 cStringArray
变量将包含与String的二维数组相对应的Class(即与String[][].class
相同)。
原始类型包装器的 TYPE 字段
.class
语法是获取原始类型的Class的更方便且首选的方式。但是,还有另一种获取Class的方法。每个原始类型和void
在java.lang中都有一个包装器类,用于将原始类型装箱到引用类型。每个包装器类都包含一个名为TYPE
的字段,该字段与要包装的原始类型的Class相等。
Class c = Double.TYPE;
有一个java.lang.Double类,用于在需要Object时包装原始类型double
。 Double.TYPE的值与double.class
的值相同。
Class c = Void.TYPE;
Void.TYPE与void.class
相同。
返回类的方法
有几种反射 API 返回类,但是只有在已经直接或间接获得Class的情况下,才可以访问这些 API。
-
- 返回给定类的超类。
Class c = javax.swing.JButton.class.getSuperclass();
javax.swing.JButton的超类是javax.swing.AbstractButton。
-
- 返回属于该类成员的所有公共类,interface和枚举,包括继承的成员。
Class<?>[] c = Character.class.getClasses();
Character包含两个成员类Character.Subset和Character.UnicodeBlock。
-
- 返回所有类interface,以及在该类中显式声明的枚举。
Class<?>[] c = Character.class.getDeclaredClasses();
Character包含两个公共成员类Character.Subset和Character.UnicodeBlock和一个私有类Character.CharacterCache
。
-
Class.getDeclaringClass()
java.lang.reflect.Field.getDeclaringClass()
java.lang.reflect.Method.getDeclaringClass()
java.lang.reflect.Constructor.getDeclaringClass()
import java.lang.reflect.Field;
Field f = System.class.getField("out");
Class c = f.getDeclaringClass();
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
包围。