У меня есть следующие классы 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()
, делает нет разницы.
Если вы объявляете внутренний класс, это в основном потому, что вы не будете использовать его где-либо еще. Но они все еще разные классы. Если вы создаете объект внешнего объекта, вам не нужно объявлять внутренний.