【问题标题】:A query about class nesting in java关于java中类嵌套的一个查询
【发布时间】:2019-09-22 10:36:23
【问题描述】:
public class Outer{
    public class Inner{
    }
}

public class Main {
    public static void main(String[] args) {
        Outer objOut = new Outer();
        //Outer.Inner object1= objOut.new Inner();  // runes without a problem
        //objOut.Inner object2= objOut.new Inner(); //gives error
    }
}

这听起来可能有点业余,但是Outer.InnerobjOut.Inner 之间有什么区别。

【问题讨论】:

标签: java types inner-classes variable-declaration


【解决方案1】:

您不能将变量名称用作另一个变量的类型,而这正是您尝试对objOut.Inner 执行的操作。变量的类型是Inner(或可选Outer.Inner)。

因为Innerinner class,所以它与它的外部类的一个实例(它的封闭实例)相关联。当您创建它的实例时,您可以选择¹指定它关联的对象实例,这就是您使用 objOut.new Inner 所做的事情。

这个例子可能会让它更清楚一点:

public class Example {
    private String str;

    public class Inner {
        void show() {
            // Show the string for the Example this Inner is part of
            System.out.println(Example.this.str);
        }
    }

    public Example(String s) {
        this.str = s;
    }

    public static void main(String[] args) {
        Example e1 = new Example("e1");
        Example e2 = new Example("e2");
        Inner i1 = e1.new Inner();
        i1.show(); // "e1"
        Inner i2 = e2.new Inner();
        i2.show(); // "e2"
    } 
}

Live Copy

注意i1 Inner 实例如何将e1 作为其封闭的Example 实例,因此看到e1str,但i2e2 作为其封闭实例所以它看到e2str

我建议this Java tutorial 了解更多信息。


¹ 有时它不是可选的,例如在我上面的Example 类中,因为在使用new Inner 的地方,它没有可以使用的默认实例。它在Exampleinstance 方法中是可选的,但在static 方法中不是。

【讨论】:

    【解决方案2】:

    这个:

    Outer.Inner = objOut.new Inner();
    

    不会编译,但如果你把它改成:

    Outer.Inner object = objOut.new Inner();
    

    将意味着创建一个引用Outer 类的内部类实例-objOut 将是Outer 类的实例。

    还有这个:

    objOut.Inner = objOut.new Inner();
    

    不会编译,因为objOutOuter 类的实例,它没有属性Inner

    知道Inner 类的实例的不是Outer 类-知道创建它的Outer 类实例的是Inner 类实例。

    编辑

    行:

    objOut.Inner object2= objOut.new Inner();
    

    将无法编译,因为Inner 类型标识符属于Outer ,而不是此类的实例。

    【讨论】:

      【解决方案3】:

      两者都不编译。

      要使前者编译,应声明一个变量,并给出该变量的名称。

      Outer.Inner obj = objOut.new Inner();
      

      即使您执行了此步骤,后者也不会编译,因为 objOut.Inner 既不是类型(因为主表达式 objOut 不是类型)也不是有效名称(因为 . 不允许在 @ 987654321@)。

      为您的案例简化的rule (jls-14.4)

      LocalVariableType VariableDeclaratorId [= VariableInitializer];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多