为毛 HashMap 里 comparableClassFor 方法要判断 p.getActualTypeArguments()返回的数组大小呢?

2019-12-07 19:23:52 +08:00
 amiwrong123
    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 吗?

2452 次点击
所在节点    Java
2 条回复
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)
amiwrong123
2019-12-19 10:00:43 +08:00
@qwerthhusn
不知道为啥我没看见你的回复提醒。。。

确实复杂,我当时看这段代码看了好久。。

算了,as.length == 1 这里虽然有点多余,但是显得很严谨,哈哈哈哈。

你说的字节码增强,难道说有可能改变 Comparable 的接口定义,使得尖括号里面的类型参数变成两个或者更多吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/626854

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX