Рассмотрим следующий набор выражений:
class T {{
/*1*/ Object o = T.super; // error: '.' expected
/*2*/ o.toString();
}}
Попытка скомпилировать это приведет к сбою в строке /*1*/ с ошибкой:
error: '.' expected
o = T.super;
^
как при использовании OpenJDK 1.8.0 (Ubuntu), так и в Oracle JDK 1.8 (Windows).
Однако Eclipse 4.5.0 (Mars) компилирует без ошибок, и это приводит к:
class T {
T();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8] // super()
4 aload_0 [this]
5 astore_1 [o] // o = T.super
7 invokevirtual java.lang.Object.toString() : java.lang.String [10]
10 pop // ^-- o.toString()
11 return
}
Из этого вы можете видеть, что строка /*1*/ java-кода (строка 5 результата) правильно хранит this, отлитую как Object (понимание Eclipse T.super) в локальной переменной o. Когда код выполняется, он завершается нормально, а строка /*2*/ создает правильный результат.
До сих пор мне не удалось найти что-либо относящееся к o = T.super; в Java 8 Language Specification, то есть, является ли оно законным или нет. Поскольку в нем явно не указано, что это юридическое выражение, я предполагаю, что оно означает незаконно. Но почему, почему Eclipse считает это законным? Отсюда мой вопрос:
Является ли T.super юридическим выражением в соответствии с JLS?
Изменить: упростить код, удалив внутренний класс упаковки.