内在候选静态方法引用一段时间后就消失了?

问题描述 投票:0回答:2

我有以下

Comparator
实现:

private static final class ValueComparator<Value_, Point_ extends Comparable<Point_>> implements Comparator<Value_> {

    private final Function<Value_, Point_> indexFunction;

    public ValueComparator(Function<Value_, Point_> indexFunction) {
        this.indexFunction = Objects.requireNonNull(indexFunction);
    }

    @Override
    public int compare(Value_ o1, Value_ o2) {
        if (o1 == o2) {
            return 0;
        }
        Point_ point1 = indexFunction.apply(o1);
        Point_ point2 = indexFunction.apply(o2);
        if (point1 == point2) {
            return 0;
        }
        int comparison = point1.compareTo(point2);
        if (comparison != 0) {
            return comparison;
        }
        // Identity Hashcode for duplicate protection; we must always include duplicates.
        // Ex: two different games on the same time slot
        int identityHashCode1 = System.identityHashCode(o1);
        int identityHashCode2 = System.identityHashCode(o2);
        return Integer.compare(identityHashCode1, identityHashCode2);
    }
}

这段代码运行了一段时间,然后突然抛出一个 NPE -

indexFunction
不知何故变成了
null
,即使它在构造函数中被检查为非空。

显然,这让我很烦恼,所以我去查找,发现

indexFunction
Math::abs
,对静态方法的引用。
java.lang.Math.abs(int)
@HotSpotIntrinsicCandidate

这是否意味着 HotSpot 在某些时候内在化了方法,因此方法引用变得无效?我该如何保护自己免受此类事情的侵害?

$ java -version
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment Temurin-11.0.12+7 (build 11.0.12+7)
OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (build 11.0.12+7, mixed mode)
java intrinsics jvm-hotspot
2个回答
2
投票

事实证明答案要简单得多,而且也不那么耸人听闻。

indexFunction
的参数为空,并且函数期望
int
,NPE 来自拆箱。在这种情况下,NPE 仍然指向
indexFunction
,而不是其中的某些代码,这最初使我走上了完全错误的道路。

显然我并没有像我想象的那样彻底检查我的输入。菜鸟错误,案件已结。


-1
投票

你遇到了一个错误,看到了一些你不理解的东西,而且,显然你已经无计可施,无法理解你的代码如何受到指责,放大了这个你不理解的东西:一定是它!

通常这不是一个很好的调试方法。 Java bug 或设计白痴解释你的问题的可能性是无限小的(因为说实话,如果

final
变量随机消失在稀薄的空气中,要么以某种方式变成
null
,或者更糟糕的是,保持原来的样子,但任何尝试与它交互会导致“哦,函数消失了”,而这是由 NullPointerException 处理的 - 这很愚蠢)。这是使用拥有众多用户的语言的优势之一。你是第一个遇到它的几率非常低。 我知道,由于现已确认的 JVM 错误,我曾在一次 Google Code Jam 挑战赛中失败。所以它

可能

发生。但可能性是无限小的。

这是否意味着 HotSpot 在某些时候内在化了方法,因此方法引用变得无效?

不。那是不可能的。这不是“内在”的含义或含义。

我该如何保护自己免受此类事情的侵害?

你不能,这很好,因为你不必这样做 - 这永远不会发生。

检查您的堆栈跟踪。

indexFunction

不为空。然而,索引函数可能会抛出 NPE,如果

o1
为空且 o2 不为空,则可能会抛出 NPE,反之亦然。
另外一点,你为什么要编写这段代码?这已经存在于 JVM 中:
而不是打电话:

new ValueComparator(x -> x.getPoint());

您只需拨打:

Comparator.comparing(x -> x.getPoint()).thenComparingInt(System::identityHashCode);

© www.soinside.com 2019 - 2024. All rights reserved.