我正在为SCJP做准备,在阅读嵌套类型时我感到困惑。有一个简单的问题,我无法理解结果。
public class Outer {
private int innerCounter;
class Inner {
Inner() {
innerCounter++;
}
public String toString() {
return String.valueOf(innerCounter);
}
}
private void multiply() {
Inner inner = new Inner();
this.new Inner();
System.out.print(inner);
inner = new Outer().new Inner();
System.out.println(inner);
}
public static void main(String[] args) {
new Outer().multiply();
}
}
打印
21
知道计数器不是静态的,前两个对象如何被视为一个对象?
答案 0 :(得分:3)
非静态内部类可以访问其外部类的所有成员。它就像它真正被定义为:
class Outer {
private int innerCount;
class Inner() {
private final Outer owner;
public Inner(Outer owner) {
this.owner = owner;
this.owner.innerCount++;
}
}
private void multiply() {
Inner inner = new Inner(this);
...
}
}
所以让我注释你的方法:
private void multiply() {
// this.innerCount = 0
Inner inner = new Inner();
// this.innerCount = 1
this.new Inner();
// this.innerCount = 2
System.out.print(inner); // Prints "2"
// Creates a new Outer (with a separate innerCount)
// then uses that to create a new Inner, which updates
// the new innerCount
inner = new Outer().new Inner();
// inner.innerCount = 1
System.out.println(inner); // Prints "1"
}
答案 1 :(得分:1)
我假设您在谈论内部对象。 好吧,它们不被视为一个对象,但它们被链接到同一个外部对象(这个)
答案 2 :(得分:1)
实例化非静态内部类需要引用“外部”类。对于方法multiply
,您已经有Outer
个活动的实例,因此new Inner()
和this.new Inner()
都引用相同的Outer
对象,但是独特的物体本身。基本上,所有嵌套的非静态类实例都在内部始终绑定到Outer
类实例。
答案 3 :(得分:0)
我没有得到你所说的'两个第一个对象',但是
innerCounter
是外类的字段。
在您的代码中,您创建了两个Outer实例 - 此处为new Outer().multiply();
,此处为inner = new Outer().new Inner();
。
第一个外部实例的innerCounter
通过调用Inner
构造函数两次(Inner inner = new Inner();
和this.new Inner();
)来增加,第二个 - 只需一次(inner = new Outer().new Inner();
)
因此你得到2和1作为输出。
答案 4 :(得分:0)
Inner inner = new Inner();
Inner inner = this.new Inner();
以上两者都是相同的,因为它们都引用了当前运行的Outer
实例。
与以下相同:
private int number;
public int getNumber(){
return this.number;
}
public int getNumber(){
return number;
}
这两种方法都引用同一个实例,因此this
不会影响输出。
答案 5 :(得分:0)
我不明白你的困惑在哪里,但我会试着解释为什么它打印21。 请参阅内联评论
注意:对象是为了解释而命名的。
public class Outer {
private int innerCounter;
class Inner {
Inner() {
innerCounter++;
}
public String toString() {
return String.valueOf(innerCounter);
}
}
private void multiply() {
Inner inner = new Inner();//Step2: Create first inner object
//Lets call it innerA
//Note innerA is created using outerA
//Increments the innerCount variable of outerA
this.new Inner(); //step3 create second inner object
//Lets call it innerB
//Note innerB is created using outerA
//Increments the innerCount variable of outerA
System.out.print(inner); //step 3 print innerCount from outerA
//With the two increments done, prints 2
inner = new Outer().new Inner(); //step4 create second outer object
//Lets call it outerB.
//Lets call this third inner object as InnerC
//InnerC creation increments OuterB's innerCount variable (so value 1)
//Assigned now to the old reference
System.out.println(inner); // prints the value of innerC
}
public static void main(String[] args) {
new Outer().multiply(); //Step1: Create the first outer object
//Lets call it OuterA
}
}