Происхождение синтаксиса Java для создания нового экземпляра внутреннего класса? - PullRequest
12 голосов
/ 03 мая 2011

Мне любопытно, как выбрать синтаксис для создания экземпляра внутреннего класса с учетом экземпляра внешнего класса в Java.

Синтаксис:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Но почему это не так:

OuterClass.InnerClass innerObject = new outerObject.InnerClass(); 

Первое, кажется, подразумевает, что new - это метод или оператор, непосредственно связанный с классом, но я понимаю, что это не так (в отличие от C ++)?

Ответы [ 3 ]

9 голосов
/ 03 мая 2011

Последнее подразумевало бы для меня, что type name было outerObject.InnerClass - тогда как на самом деле typename просто InnerClass (или OuterClass.InnerClass, что также было бы допустимо), построено отношение к экземпляру, указанному outerObject.

Лично мне не нравится, как Java делает вложенные классы в первую очередь, и я согласен, что это выглядит немного странно, но я могупонять, почему это так.

3 голосов
/ 03 мая 2011

Есть и другая причина.

new o.C(); 

имеет два возможных значения.Это может означать создание внутреннего класса C в контексте внешнего объекта o.Это также может быть создание класса с полностью определенным именем o.C.Эта двусмысленность проблематична, тем более что обе интерпретации могут быть действительны одновременно.

1 голос
/ 03 мая 2011

Внутренний класс является подмножеством, во всех отношениях, неотъемлемой части внешнего класса. Внутренний класс может получить доступ ко всем членам внешнего класса, как если бы они были одним. Точно так же экземпляр (не static) внутреннего класса должен быть внутренней частью экземпляра внешнего класса. Он не может существовать сам по себе. Вы можете сравнить это с тем, как вы не можете получить доступ к нестатической переменной или функции с помощью MyClass.wyVariable.

Это поднимает вопрос о том, какой способ является наиболее семантически правильным способом представления этих отношений.

OuterClass.InnerClass innerObject = new outerObject.InnerClass();

... будет (семантически) утверждать, что InnerClass является каким-то образом свойством outerObject, которое после извлечения может свободно обрабатываться в мире, выходящем за рамки outerObject. new в этом случае не будет ничего особенного.

Скорее InnerClass является частью OuterClass, тогда как экземпляр из InnerClass должен быть частью экземпляра из OuterClass.

Синтаксис выше будет символизировать, что InnerClass (сам класс) является частью некоторого экземпляра OuterClass, что семантически неверно. В конце концов, существует только один класс InnerClass, даже если этот класс может иметь любое количество экземпляров.

OuterClass.InnerClass innerObject = new OuterClass.InnerClass();

..., конечно, также (семантически) будет некорректно для не static внутренних классов, так как это никоим образом не представляет особые отношения любви и заботы между экземплярами внутреннего и внешнего классов.

Обратите внимание, что этот синтаксис отлично подходит для static внутренних классов, так как они не имеют особой связи ни с одним экземпляром внешнего класса. Это также прекрасно, когда создается экземпляр внутреннего класса внутри его внешнего класса.

Наконец,

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

... лучше символизирует отношения. Это символизирует, что процесс создания экземпляра однозначно привязан к одному конкретному внешнему объекту, что имеет место.

...