Почему JVM учитывает суперинтерфейсы при разрешении неинтерфейсных методов? (JVM 5.4.3.3) - PullRequest
6 голосов
/ 23 апреля 2020

JVM spe c ( 5.4.3.3 ) описывает, как выполняется разрешение метода для ссылок на метод. Если он не может найти метод в классе или его суперклассах, он пытается найти метод в суперинтерфейсе.

В чем причина этого? Разве метод, объявленный суперинтерфейсом, не будет указан в пуле констант как метод интерфейса ref вместо метода ref?

Насколько я понимаю, ссылки на метод используются в операциях invokevirtual, тогда как метод интерфейса - ссылки используются в invokeinterface операциях. Я не понимаю, как можно вызвать метод интерфейса, используя invokevirtual <methodref>.

1 Ответ

5 голосов
/ 23 апреля 2020

Почему бы и нет?

Вы можете вызвать .stream() на ArrayList<> просто отлично. Фактически, следующий фрагмент

ArrayList<Object> arr = new ArrayList<>();
arr.stream();

будет скомпилирован в

     0: new           #16                 // class java/util/ArrayList
     3: dup
     4: invokespecial #18                 // Method java/util/ArrayList."<init>":()V
     7: astore_1
     8: aload_1
     9: invokevirtual #19                 // Method java/util/ArrayList.stream:()Ljava/util/stream/Stream;

Но ArrayList<> (или любой из его суперклассов) не имеет .stream() метода.
Используемая реализация метода взята из interface Collection:

default Stream<E> stream() {
    return StreamSupport.stream(spliterator(), false);
}

Но если в какой-то момент ArrayList<> решит, что он может обеспечить лучший метод .stream(), то вы не Я не хочу снова компилировать ваш код.
Также реализация (или нереализация) метода .stream() протекает, и лучше этого избежать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...