不了解嵌套类型

时间:2011-12-17 18:15:35

标签: java object inner-classes nested-class

我正在为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

知道计数器不是静态的,前两个对象如何被视为一个对象?

6 个答案:

答案 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

} }