Skip to content

Commit c036191

Browse files
authored
Update 06_Reflecting_Generic_Types.md
1 parent a968560 commit c036191

File tree

1 file changed

+125
-116
lines changed

1 file changed

+125
-116
lines changed

ch07/06_Reflecting_Generic_Types.md

+125-116
Original file line numberDiff line numberDiff line change
@@ -5,33 +5,35 @@
55

66
反射库提供了一个 `Type` 接口来描述一个通用类型。 有一个类实现了这个接口和四个其他接口来扩展它,对应于五种不同的类型:
77

8-
- `Class` 类,表示原始类型或原始类型
9-
10-
- 接口 `ParameterizedType`,表示通用类或接口的参数类型的应用程序,您可以从中提取参数类型的数组
11-
12-
- `TypeVariable` 接口,代表一个类型变量,从中可以提取类型变量的边界
13-
14-
- `GenericArrayType` 接口,表示数组,您可以从中提取数组组件类型
15-
16-
- `WildcardType` 接口,表示通配符,您可以从中抽取通配符的下限或上限
17-
8+
- `Class` 类,表示原始类型或原始类型
9+
10+
- 接口 `ParameterizedType`,表示通用类或接口的参数类型的应用程序,您可以从中提取参数类型的数组
11+
12+
- `TypeVariable` 接口,代表一个类型变量,从中可以提取类型变量的边界
13+
14+
- `GenericArrayType` 接口,表示数组,您可以从中提取数组组件类型
15+
16+
- `WildcardType` 接口,表示通配符,您可以从中抽取通配符的下限或上限
17+
1818
通过在每个接口上执行一系列实例测试,您可以确定您拥有哪种类型,并打印或处理类型;我们将很快看到一个例子。
1919

2020
方法可用于将类的超类和超接口作为类型返回,并访问字段的泛型类型,构造函数的参数类型以及方法的参数和结果类型。
2121

22-
您还可以提取代表类或接口声明或泛型方法或构造函数的形式参数的类型变量。类型变量的类型需要一个参数,并写入 `TypeVariable<D>`,其中 `D` 表示声明类型变量的对象的类型。因此,类的类型变量具有类型 `TypeVariable<Class<?>>`,而泛型方法的类型变量具有类型 `TypeVariable<Method>`。可以说,类型参数是令人困惑的,并不是非常有用。由于它对 `6.6` 节中描述的问题负责,因此 `Sun` 可能会在将来删除它。
22+
您还可以提取代表类或接口声明或泛型方法或构造函数的形式参数的类型变量。类型变量的类型需要一个参数,并写入 `TypeVariable<D>`,其中 `D` 表示声明类型变
23+
量的对象的类型。因此,类的类型变量具有类型 `TypeVariable<Class<?>>`,而泛型方法的类型变量具有类型 `TypeVariable<Method>`。可以说,类型参数是令人
24+
困惑的,并不是非常有用。由于它对 `6.6` 节中描述的问题负责,因此 `Sun` 可能会在将来删除它。
2325

2426
`7-5` 使用这些方法打印出与类关联的所有标题信息。这里有两个使用例子:
2527

2628
```java
27-
% java ReflectionDemo java.util.AbstractList
28-
class java.util.AbstractList<E>
29-
extends java.util.AbstractCollection<E>
30-
implements java.util.List<E>
31-
32-
% java ReflectionDemo java.lang.Enum
33-
class java.lang.Enum<E extends java.lang.Enum<E>>
34-
implements java.lang.Comparable<E>,java.io.Serializable
29+
% java ReflectionDemo java.util.AbstractList
30+
class java.util.AbstractList<E>
31+
extends java.util.AbstractCollection<E>
32+
implements java.util.List<E>
33+
34+
% java ReflectionDemo java.lang.Enum
35+
class java.lang.Enum<E extends java.lang.Enum<E>>
36+
implements java.lang.Comparable<E>,java.io.Serializable
3537
```
3638

3739
例 `7-5` 中的代码冗长而直接。 它包含打印类的每个组件的方法:它的超类,它的接口,它的字段和它的方法。 代码的核心是 `printType` 方法,它使用级联的实
@@ -40,109 +42,116 @@
4042
例 `7-5`。 如何操作 `Type` 类型
4143

4244
```java
43-
import java.util.*;
44-
import java.lang.reflect.*;
45-
import java.io.*;
46-
class ReflectionDemo {
47-
private final static PrintStream out = System.out;
48-
public static void printSuperclass(Type sup) {
49-
if (sup != null && !sup.equals(Object.class)) {
50-
out.print("extends ");
51-
printType(sup);
52-
out.println();
53-
}
54-
}
55-
public static void printInterfaces(Type[] impls) {
56-
if (impls != null && impls.length > 0) {
57-
out.print("implements ");
58-
int i = 0;
59-
for (Type impl : impls) {
60-
if (i++ > 0) out.print(",");
61-
printType(impl);
62-
}
63-
out.println();
64-
}
65-
}
66-
public static void printTypeParameters(TypeVariable<?>[] vars) {
67-
if (vars != null && vars.length > 0) {
68-
out.print("<");
69-
int i = 0;
70-
for (TypeVariable<?> var : vars) {
71-
if (i++ > 0) out.print(",");
72-
out.print(var.getName());
73-
printBounds(var.getBounds());
74-
}
75-
out.print(">");
76-
}
77-
}
78-
public static void printBounds(Type[] bounds) {
79-
if (bounds != null && bounds.length > 0 && !(bounds.length == 1 && bounds[0] == Object.class)) {
80-
out.print(" extends ");
81-
int i = 0;
82-
for (Type bound : bounds) {
83-
if (i++ > 0) out.print("&");
84-
printType(bound);
85-
}
86-
}
45+
import java.util.*;
46+
import java.lang.reflect.*;
47+
import java.io.*;
48+
class ReflectionDemo {
49+
private final static PrintStream out = System.out;
50+
public static void printSuperclass(Type sup) {
51+
if (sup != null && !sup.equals(Object.class)) {
52+
out.print("extends ");
53+
printType(sup);
54+
out.println();
55+
}
56+
}
57+
public static void printInterfaces(Type[] impls) {
58+
if (impls != null && impls.length > 0) {
59+
out.print("implements ");
60+
int i = 0;
61+
for (Type impl : impls) {
62+
if (i++ > 0)
63+
out.print(",");
64+
printType(impl);
8765
}
88-
public static void printParams(Type[] types) {
89-
if (types != null && types.length > 0) {
90-
out.print("<");
91-
int i = 0;
92-
for (Type type : types) {
93-
if (i++ > 0) out.print(",");
94-
printType(type);
95-
}
96-
out.print(">");
97-
}
66+
out.println();
67+
}
68+
}
69+
public static void printTypeParameters(TypeVariable<?>[] vars) {
70+
if (vars != null && vars.length > 0) {
71+
out.print("<");
72+
int i = 0;
73+
for (TypeVariable<?> var : vars) {
74+
if (i++ > 0)
75+
out.print(",");
76+
out.print(var.getName());
77+
printBounds(var.getBounds());
9878
}
99-
public static void printType(Type type) {
100-
if (type instanceof Class) {
101-
Class<?> c = (Class)type;
102-
out.print(c.getName());
103-
} else if (type instanceof ParameterizedType) {
104-
ParameterizedType p = (ParameterizedType)type;
105-
Class c = (Class)p.getRawType();
106-
Type o = p.getOwnerType();
107-
if (o != null) { printType(o); out.print("."); }
108-
out.print(c.getName());
109-
printParams(p.getActualTypeArguments());
110-
} else if (type instanceof TypeVariable<?>) {
111-
TypeVariable<?> v = (TypeVariable<?>)type;
112-
out.print(v.getName());
113-
} else if (type instanceof GenericArrayType) {
114-
GenericArrayType a = (GenericArrayType)type;
115-
printType(a.getGenericComponentType());
116-
out.print("[]");
117-
} else if (type instanceof WildcardType) {
118-
WildcardType w = (WildcardType)type;
119-
Type[] upper = w.getUpperBounds();
120-
Type[] lower = w.getLowerBounds();
121-
if (upper.length == 1 && lower.length == 0) {
122-
out.print("? extends ");
123-
printType(upper[0]);
124-
} else if (upper.length == 0 && lower.length == 1) {
125-
out.print("? super ");
126-
printType(lower[0]);
127-
} else
128-
throw new AssertionError();
129-
}
79+
out.print(">");
80+
}
81+
}
82+
public static void printBounds(Type[] bounds) {
83+
if (bounds != null && bounds.length > 0 && !(bounds.length == 1 && bounds[0] == Object.class)) {
84+
out.print(" extends ");
85+
int i = 0;
86+
for (Type bound : bounds) {
87+
if (i++ > 0)
88+
out.print("&");
89+
printType(bound);
13090
}
131-
public static void printClass(Class c) {
132-
out.print("class ");
133-
out.print(c.getName());
134-
printTypeParameters(c.getTypeParameters());
135-
out.println();
136-
printSuperclass(c.getGenericSuperclass());
137-
printInterfaces(c.getGenericInterfaces());
91+
}
92+
}
93+
public static void printParams(Type[] types) {
94+
if (types != null && types.length > 0) {
95+
out.print("<");
96+
int i = 0;
97+
for (Type type : types) {
98+
if (i++ > 0)
99+
out.print(",");
100+
printType(type);
138101
}
139-
public static void main(String[] args) throws ClassNotFoundException {
140-
for (String name : args) {
141-
Class<?> c = Class.forName(name);
142-
printClass(c);
143-
}
102+
out.print(">");
103+
}
104+
}
105+
public static void printType(Type type) {
106+
if (type instanceof Class) {
107+
Class<?> c = (Class)type;
108+
out.print(c.getName());
109+
} else if (type instanceof ParameterizedType) {
110+
ParameterizedType p = (ParameterizedType)type;
111+
Class c = (Class)p.getRawType();
112+
Type o = p.getOwnerType();
113+
if (o != null) {
114+
printType(o);
115+
out.print(".");
144116
}
117+
out.print(c.getName());
118+
printParams(p.getActualTypeArguments());
119+
} else if (type instanceof TypeVariable<?>) {
120+
TypeVariable<?> v = (TypeVariable<?>)type;
121+
out.print(v.getName());
122+
} else if (type instanceof GenericArrayType) {
123+
GenericArrayType a = (GenericArrayType)type;
124+
printType(a.getGenericComponentType());
125+
out.print("[]");
126+
} else if (type instanceof WildcardType) {
127+
WildcardType w = (WildcardType)type;
128+
Type[] upper = w.getUpperBounds();
129+
Type[] lower = w.getLowerBounds();
130+
if (upper.length == 1 && lower.length == 0) {
131+
out.print("? extends ");
132+
printType(upper[0]);
133+
} else if (upper.length == 0 && lower.length == 1) {
134+
out.print("? super ");
135+
printType(lower[0]);
136+
} else
137+
throw new AssertionError();
138+
}
139+
}
140+
public static void printClass(Class c) {
141+
out.print("class ");
142+
out.print(c.getName());
143+
printTypeParameters(c.getTypeParameters());
144+
out.println();
145+
printSuperclass(c.getGenericSuperclass());
146+
printInterfaces(c.getGenericInterfaces());
147+
}
148+
public static void main(String[] args) throws ClassNotFoundException {
149+
for (String name : args) {
150+
Class<?> c = Class.forName(name);
151+
printClass(c);
145152
}
153+
}
154+
}
146155
```
147156

148157
如果 `Type` 接口有一个 `toGenericString` 方法,那么大部分代码都是不必要的。 `Sun` 正在考虑这一改变。

0 commit comments

Comments
 (0)