static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) { // 首先检查 x 是否可以转型为 Comparable
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class) // 如果类型是 String 则直接返回,因为 String 是泛型自限定的
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;
}
这个函数里的逻辑大概都看懂了,就一个地方,为什么一定要加 as.length == 1 呢?
我想之所以要判断 as.length == 1,是因为 length 确实可能为 0,但如果前面的判断都通过了,那就说明尖括号肯定有东西了啊,而且 Comparable 的接口定义里,类型参数就一个啊,那就直接 as[0] == c 就好了啊,不用判断 as.length == 1 了啊?
还是说真的有那种情况,就算前面的判断都通过了,as.length 还是可能为 0 吗?
1
qwerthhusn 2019-12-09 15:04:27 +08:00
Java 5 之后类型系统就变得极其复杂了、、、、
我估计是为了应对 Java 字节码增强的那些技术吧,我不知道那些字节码增强能不能改动 jdk 内部的类。。。 正常情况下,如果 Type 是 ParameterizedType,getActualTypeArguments 应该不会返回 null 的。RawType 是 Comparable,,,getActualTypeArguments 数组长度也该是 1 我们自己写可能就变成了这样 if ((t instanceof ParameterizedType) && ((p = (ParameterizedType)t).getRawType() == Comparable.class) && p.getActualTypeArguments()[0] == c) |
2
amiwrong123 OP @qwerthhusn
不知道为啥我没看见你的回复提醒。。。 确实复杂,我当时看这段代码看了好久。。 算了,as.length == 1 这里虽然有点多余,但是显得很严谨,哈哈哈哈。 你说的字节码增强,难道说有可能改变 Comparable 的接口定义,使得尖括号里面的类型参数变成两个或者更多吗 |