# 检索类对象

> 原文： [https://docs.oracle.com/javase/tutorial/reflect/class/classNew.html](https://docs.oracle.com/javase/tutorial/reflect/class/classNew.html)

所有反射操作的入口点是 [`java.lang.Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。除 [`java.lang.reflect.ReflectPermission`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ReflectPermission.html) 外， [`java.lang.reflect`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/package-summary.html) 中没有一类具有公共构建体。要进入这些类，有必要在 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 上调用适当的方法。根据代码是否可以访问对象，类的名称，类型或现有的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) ，有几种方法可以获得 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

## Object.getClass（）

如果对象的实例可用，则获取其 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 的最简单方法是调用 [`Object.getClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--) 。当然，这仅适用于所有继承自 [`Object`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html) 的参考类型。一些例子如下。

```
Class c = "foo".getClass();

```

返回 [`String`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) 的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html)

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

```

有一个与`static`方法 [`System.console()`](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#console--) 返回的虚拟机关联的唯一控制台。 [`getClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--) 返回的值是对应于 [`java.io.Console`](https://docs.oracle.com/javase/8/docs/api/java/io/Console.html) 的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

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

```

`A`是枚举`E`的实例;因此 [`getClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--) 返回对应于枚举类型`E`的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

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

```

由于数组是 [`Objects`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html) ，因此也可以在数组实例上调用 [`getClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--) 。返回的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 对应于组件类型为`byte`的数组。

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

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

```

在这种情况下， [`java.util.Set`](https://docs.oracle.com/javase/8/docs/api/java/util/Set.html) 是 [`java.util.HashSet`](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html) 类型的对象的接口。 [`getClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--) 返回的值是 [`java.util.HashSet`](https://docs.oracle.com/javase/8/docs/api/java/util/HashSet.html) 对应的类别。

## .class 语法

如果类型可用但没有实例，则可以通过将`".class"`附加到类型名称来获得 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。这也是获得原始类型的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 的最简单方法。

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

Class c = boolean.class;  // correct

```

请注意，语句`boolean.getClass()`会产生编译时错误，因为`boolean`是基本类型，无法解除引用。 `.class`语法返回与`boolean`类型对应的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

```
Class c = java.io.PrintStream.class;

```

变量`c`将是与 [`java.io.PrintStream`](https://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.html) 类型对应的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

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

```

`.class`语法可用于检索对应于给定类型的多维阵列的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

## 的 Class.forName（）

如果类的完全限定名称可用，则可以使用静态方法 [`Class.forName()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-) 获得相应的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。这不能用于原始类型。 [`Class.getName()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getName--) 描述了数组类名称的语法。此语法适用于引用和基元类型。

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

```

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

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

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

```

变量`cDoubleArray`将包含对应于基本类型`double`的数组的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) （即与`double[].class`相同）。 `cStringArray`变量将包含对应于 [`String`](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) 的二维阵列的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) （即与`String[][].class`相同）。

## 原始类型包装的 TYPE 字段

`.class`语法是获取原始类型的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 的更方便和优选的方法;然而，有另一种方法来获得 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。每个基本类型和`void`在 [`java.lang`](https://docs.oracle.com/javase/8/docs/api/java/lang/package-summary.html) 中都有一个包装类，用于将基元类型装箱到引用类型。每个包装类包含一个名为`TYPE`的字段，它等于被包装的基本类型的 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 。

```
Class c = Double.TYPE;

```

有一个类 [`java.lang.Double`](https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html) ，用于在需要 [`Object`](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html) 时包装原始类型`double`。 [`Double.TYPE`](https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#TYPE) 的值与`double.class`的值相同。

```
Class c = Void.TYPE;

```

[`Void.TYPE`](https://docs.oracle.com/javase/8/docs/api/java/lang/Void.html#TYPE) 与`void.class`相同。

## 返回类的方法

有几个 Reflection API 返回类，但只有在直接或间接获得 [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) 时才能访问这些类。

[`Class.getSuperclass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getSuperclass--)

Returns the super class for the given class.

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

```

The super class of [`javax.swing.JButton`](https://docs.oracle.com/javase/8/docs/api/javax/swing/JButton.html) is [`javax.swing.AbstractButton`](https://docs.oracle.com/javase/8/docs/api/javax/swing/AbstractButton.html).

[`Class.getClasses()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getClasses--)

Returns all the public classes, interfaces, and enums that are members of the class including inherited members.

```
Class&lt;?&gt;[] c = Character.class.getClasses();

```

[`Character`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html) contains two member classes [`Character.Subset`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.Subset.html) and [`Character.UnicodeBlock`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.UnicodeBlock.html).

[`Class.getDeclaredClasses()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredClasses--)

Returns all of the classes interfaces, and enums that are explicitly declared in this class.

```
Class&lt;?&gt;[] c = Character.class.getDeclaredClasses();

```

[`Character`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html) contains two public member classes [`Character.Subset`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.Subset.html) and [`Character.UnicodeBlock`](https://docs.oracle.com/javase/8/docs/api/java/lang/Character.UnicodeBlock.html) and one private class `Character.CharacterCache`.

[`Class.getDeclaringClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaringClass--)
[`java.lang.reflect.Field.getDeclaringClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html#getDeclaringClass--)
[`java.lang.reflect.Method.getDeclaringClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Method.html#getDeclaringClass--)
[`java.lang.reflect.Constructor.getDeclaringClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Constructor.html#getDeclaringClass--)

Returns the [`Class`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html) in which these members were declared. [Anonymous Class Declarations](https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5) will not have a declaring class but will have an enclosing class.

```
import java.lang.reflect.Field;

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

```

The field [`out`](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#out) is declared in [`System`](https://docs.oracle.com/javase/8/docs/api/java/lang/System.html).

```
public class MyClass {
    static Object o = new Object() {
        public void m() {} 
    };
    static Class&lt;c&gt; = o.getClass().getEnclosingClass();
}

```

The declaring class of the anonymous class defined by `o` is `null`.

[`Class.getEnclosingClass()`](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getEnclosingClass--)

Returns the immediately enclosing class of the class.

```
Class c = Thread.State.class().getEnclosingClass();

```

The enclosing class of the enum [`Thread.State`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.State.html) is [`Thread`](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html).

```
public class MyClass {
    static Object o = new Object() { 
        public void m() {} 
    };
    static Class&lt;c&gt; = o.getClass().getEnclosingClass();
}

```

The anonymous class defined by `o` is enclosed by `MyClass`.