Рассмотрим следующий набор выражений:
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, то есть законно это или нет. Поскольку в нем прямо не указано, что это допустимое выражение, я предполагаю, что это означает, что оно незаконно. Но тогда почему Eclipse считает это законным? Отсюда мой вопрос:
Является ли T.super
допустимым выражением согласно JLS?
Редактировать: упростили код, удалив внутренний класс-оболочку.
toString
для экземпляраT
, еслиtoString
переопределен. - person Sam Sun   schedule 07.01.2016new ArrayList<>() {{add(something);}}
. Не очень элегантный способ, поскольку он создает ненужный анонимный класс, но все же. - person Sergei Tachenov   schedule 07.01.2016