对ParameterizedType的理解

在翻看jdk源码时发现java.util.HashMap#comparableClassFor方法中的代码,有点疑惑,然后就去学习了解ParameterizedType的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* Returns x's Class if it is of the form "class C implements
* Comparable<C>", else null.
*/
static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) {
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class) // bypass checks
return c;
if ((ts = c.getGenericInterfaces()) != null) {
for (int i = 0; i < ts.length; ++i) {
if (((t = ts[i]) instanceof ParameterizedType) &&
((p = (ParameterizedType)t).getRawType() ==
Comparable.class) &&
(as = p.getActualTypeArguments()) != null &&
as.length == 1 && as[0] == c) // type arg is c
return c;
}
}
}
return null;
}

根据注释可以清楚这个方法是干嘛。大致意思就是:如果class x是class x implements Comparable<x>的形式,那么就返回x的class,否则返回null

ParameterizedType在这里的作用就是获取类的实现的接口是<T>类型的接口,getActualTypeArguments()方法是获取接口中的参数看是否和当前类一致,因为instanceof判断是远远不够的,也有可能是上层类有实现,但是本类没有,所以需要获取本类实现的接口是不是Comparable,还有接口里面的参数是不是和本类一致的,我们直接用反射调用这个方法看下,可不可行

1
2
3
4
5
6
7
8
9
package options.jdk.Type;

public class ParamService implements Comparable<ParamService> {

@Override
public int compareTo(ParamService o) {
return 0;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package options.jdk.Type;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;

public class ReflectTest {

public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
HashMap<String, Object> map = new HashMap<>();
Method[] declaredMethods = map.getClass().getDeclaredMethods();
for (Method method : declaredMethods) {
if (method.getName().equals("comparableClassFor")) {
method.setAccessible(true);
ParamService paramService = new ParamService();
Object invoke = method.invoke(map,paramService);
System.out.println(invoke);
}
}
}
}
1
2
3
class options.jdk.Type.ParamService

Process finished with exit code 0

很明显是成功的。