Подтвердить что ты не робот

"но компилятор этого не знает" - какой смысл?

Я встретил такой код и комментарии в классе java.util.ImmutableCollections:

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
    } 
    ...
}

Почему не просто throw new IndexOutOfBoundsException(...)? Какая причина?

4b9b3361

Ответ 1

Возможно, это просто исключение дублирования кода, потому что иначе это будет что-то вроде:

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

но outOfBounds* методы private, поэтому по дизайну кто-то должен вызывать обертки, такие как return Preconditions.checkIndex(index, length, null)

Ответ 2

Если мне не хватает чего-то очевидного здесь, это намного проще. Это то же самое, что:

// 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, поэтому для return требуется инструкция s(). То же самое происходит в операторах switch для перечисления, где вы должны предоставить throw; даже если вы обработали все случаи этого перечисления.


Этот код btw используется в List0, где нет смысла вызывать get(x), потому что в списке нет никаких элементов.

Ответ 3

Реализация кажется более ориентированной на дизайн, чем просто функциональность.

Причины такого же могут быть связаны прежде всего с тем, что Preconditions.checkIndex помечен как @HotSpotIntrinsicCandidate, что означает, что исправление производительности кода запрашивается, когда этот метод используется внутри.

Кроме того, можно заметить, что весь неизменный список, содержащий 0 (пустой), 1, 2 или N элементов, созданный с использованием метода factory of, использует Objects.checkIndex(int index, int length), который в конечном итоге полагается на вышеупомянутый вызов метода, чтобы, возможно, сделать некоторые внутренние оптимизации.


Кратко о HotSpotIntrinsicCandidate из библиотеки: -

Аннотация @HotSpotIntrinsicCandidate специфична для  Виртуальная машина HotSpot. Он указывает, что аннотированный метод может (но не гарантированно) быть встроен в виртуальную машину HotSpot.

Метод встроен, если VM HotSpot заменяет аннотированный метод с рукописной сборкой и/или рукописным компилятором IR - встроенный компилятор - для повышения производительности.

Аннотация @HotSpotIntrinsicCandidate является внутренней для Java библиотек и, следовательно, не должны иметь никакого отношения к код приложения.