Ответ 1
Существует разница между реализацией и спецификацией.
По-моему, выражение "за исключением" JLS
... кроме в неединичном внутреннем классе-члене...
плохо сформулирован.
Это означает, что компилятор не требуется, чтобы неявно объявлять один формальный параметр, представляющий сразу входящий экземпляр класса... но он мог.
Почему неявный формальный параметр требуется в неединичном внутреннем классе-члене?
Из JLS 8.8.1:
Класс участника может быть испущен компилятором, который отличается от компилятора выражения создания экземпляра класса. Следовательно, должен существовать стандартный способ для компилятора выражения create передать ссылку (представляющую непосредственно входящий экземпляр) в конструктор класса-члена
Например, если я скомпилирую этот внутренний класс с первым компилятором:
package p1;
public class Ctors {
public class MyInner {
}
}
если я хочу скомпилировать этот подкласс с другим компилятором:
package p2;
import p1.Ctors;
public class SubCtors {
public SubCtors() {
new Ctors();
}
}
второй компилятор должен иметь возможность использовать конструктор по умолчанию с формальным параметром.
В этом случае экземпляр класса-оболочки с экземпляром SubCtors
.
Почему неявно формальный параметр не требуется в неединичном внутреннем классе-члене?
Потому что неединичный внутренний класс-член всегда обращается к тому же компилятору, который его скомпилировал. Как вы показали, javac генерирует один и тот же конструктор независимо от видимости класса, но для этого не требуется. Другая реализация компилятора может выбрать другой способ.
В JLS 8.8.1 есть еще один пункт, который очень похож на ту же строку
В выражении для создания экземпляра класса для локального класса (не в статическом контексте) или анонимного класса, §15.9.2 указывает непосредственно входящий экземпляр локального/анонимного класса. Локальный/анонимный класс обязательно испускается тем же компилятором, что и выражение создания экземпляра класса. Этот компилятор может представлять собой тот экземпляр, который будет немедленно включен, как он пожелает. Не требуется, чтобы язык программирования Java неявно объявлял параметр в локальном/анонимном конструкторе класса.