Ничего действительно плохого не случилось бы, если бы они были предназначены для статических вещей. На уровне файлов классов проблем нет, я думаю, что в байт-коде нет понятия внутреннего класса.
Это было бы сбивающим с толку, хотя:
class X
class Y
static int z;
X x1 = new X();
X.Y y1 = x1.new Y();
X x2 = new X();
X.Y y2 = x2.new Y();
X.Y y3 = x2.new Y();
Интуитивно, y2
и y3
должны иметь одинаковые z
, но должны ли они быть одинаковыми z
, видимыми y1
?
Концептуально внутренний класс действителен только во внешнем экземпляре. Можно даже предположить, что JVM выгружает его, когда внешний экземпляр GC'ed; аргумент, приведенный в [1] против выгрузки класса, не применяется, потому что у внутренних классов нет статической переменной или статического инициализатора.
Однако реальность такова, что существует один класс, общий для всех внутренних экземпляров, независимо от внешних экземпляров. Это, безусловно, правда: y1.getClass()==y2.getClass()==y3.getClass()
.
Можно утверждать, что языковая спецификация диктует, что это правда: [2]
Два ссылочных типа являются одним и тем же типом времени выполнения, если ... определены одним и тем же загрузчиком классов, и имеют одинаковое двоичное имя
Класс y1 и класс y2 имеют один и тот же загрузчик классов, двоичное имя X.Y четко определено и не зависит от внешнего экземпляра. Таким образом, у y1 и y2 должен быть один и тот же класс времени выполнения.
Если спецификация языка фактически подразумевает, что внутренний класс не зависит от внешнего экземпляра, общепринятое объяснение статического состояния во внутренних классах ослабляется.
[1] http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7
[2] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.4