提问者:小点点

“但编译器不知道这一点”——有什么意义?


我在java. util.ImmutableCollection类中遇到过这样的代码和注释:

static final class List0<E> extends AbstractImmutableList<E> {
    ...
    @Override
    public E get(int index) {
        Objects.checkIndex(index, 0); // always throws IndexOutOfBoundsException
        return null;                  // but the compiler doesn't know this
    } 
    ...
}

为什么不直接抛出新的IndexOutOfBoundsException(…)?原因是什么?


共3个答案

匿名用户

也许,这只是避免代码重复,因为否则它会是这样的:

new IndexOutOfBoundsException(outOfBoundsMessage(..., ...)) 

但是outOfB的*方法是私有的,所以根据设计,应该有人调用包装器,比如返回Pre条件. checkIndex(index,long,null)

匿名用户

除非我遗漏了一些显而易见的东西,否则这要简单得多。这和:

// this will not compile, *even* if test throws the Exception always
public String s() {
    test(); 
}

private void test() {
    throw new RuntimeException("just because");
}

编译器无法判断test将始终抛出RuntimeException,因此它需要s()中的back语句。同样的事情发生在枚举的switch语句中,您必须提供抛出;即使您已经处理了该枚举的所有情况。

此代码btw用于List0,其中调用get(x)没有意义,因为List中肯定没有元素。

匿名用户

这里的实现似乎更面向设计,而不仅仅是功能。

相同的原因可能主要是Pre条件. checkIndex被标记为@HotSpotIntrinsicCandidate,这意味着在内部使用此方法时寻求代码性能改进。

此外,可以注意到所有不可变列表-包含0(空)、1、2或N个元素,使用的工厂方法创建,使用Object. checkIndex(int index,int long),它最终依赖于上述方法调用来可能进行一些内部优化。

来自库的HotSpotIntrinsicCandidate简介:-

@HotSpotIntrinsicCandidate注解特定于HotSpot虚拟机。它表示带注释的方法可能(但不能保证)被HotSpotVM所包含。

如果HotSpotVM用手写程序集和/或手写编译器IR(编译器内在)替换带注释的方法以提高性能,则方法是内在的。

@HotSpotIntrinsicCandidate注释是Java库内部的,因此不应该与应用程序代码有任何关联。