У меня есть следующие классы Java:
public class Outer {
...
private class Inner {
...
}
...
}
Предположим, я внутри нестатического метода Outer. Какая разница, звоню ли я this.new Inner() или new Outer.Inner()? Гарантируется ли во втором случае, что новый Outer не будет создан?
У меня есть досадная ошибка в моей программе, которая появляется только иногда, и ее трудно найти или воспроизвести. Поэтому мне интересно, может ли эта линия создать какие-либо проблемы.
чтобы избежать этого this.new Inner() или new Outer.Inner(), вы можете объявить свой внутренний класс как класс static. private static class Inner
Я считаю, что два опубликованных вами вызова конструктора функционально идентичны (было бы другое дело, если бы вы написали new Outer().new Inner(). Но не было бы более полезным для вашего поиска опубликовать ошибку, которую вы пытаетесь устранить?
Спасибо, это был главный вопрос, идентичны ли эти две строки семантически. Но я думаю, что это вопрос знания стандарта Java, а не «веры», не так ли? :-)
Если я не устраню свою ошибку, я могу опубликовать ее, но это слишком сложно объяснить, потому что я не знаю, в какой строке кода она появляется.
Вы можете спросить себя: как он вообще теоретически сможет создать еще один экземпляр Outer? Поскольку вы не указываете его параметр конструктора, не может быть вызван пользовательский конструктор и, следовательно, не может быть создан другой Outer.
@Kolodez Вы не знаете, в какой строке возникает ошибка компиляции? Ошибки компиляции всегда указывают строку, так что это звучит неправильно.
Это не было ошибкой компиляции. Проблема заключалась в неожиданном поведении программы. Но я, наконец, нашел проблему. :-)




Они одинаковы, хотя оба излишне многословны.
Следующие 3 версии приводят к одному и тому же байт-коду:
class Outer {
private class Inner {
}
void foo() {
Inner a = this.new Inner();
Inner b = new Outer.Inner();
Inner c = new Inner(); // Recommended way to write it
}
}
Байт-код
0: new #7 // class Outer$Inner
3: dup
4: aload_0
5: invokespecial #9 // Method Outer$Inner."<init>":(LOuter;)V
8: astore_1
9: new #7 // class Outer$Inner
12: dup
13: aload_0
14: invokespecial #9 // Method Outer$Inner."<init>":(LOuter;)V
17: astore_2
18: new #7 // class Outer$Inner
21: dup
22: aload_0
23: invokespecial #9 // Method Outer$Inner."<init>":(LOuter;)V
26: astore_3
Blank lines added to improve clarity.
new Outer.Inner(); иногда бывает полезно при создании экземпляра внутреннего общедоступного статического класса из другого места. Я думаю об этом как о дополнительном квалификаторе пакета/области.
@RetoHöhener Хорошо, что вы так думаете, потому что это именно то, что есть. Точно так же this.new Inner(), или, скорее, other.new Inner(), полезен, когда вы хотите, чтобы объект Inner был связан с объектом Outer, отличным от this, что похоже на то, как вы можете получить доступ к полю, используя name или this.name, вы можете написать new Inner() или this.new Inner(), делает нет разницы.
Если вы объявляете внутренний класс, это в основном потому, что вы не будете использовать его где-либо еще. Но они все еще разные классы. Если вы создаете объект внешнего объекта, вам не нужно объявлять внутренний.