【问题标题】:Member nested classes in java?java中的成员嵌套类?
【发布时间】:2015-06-28 01:17:12
【问题描述】:

如果我们有代码...

public class Hello
{
    public static void main(String args[])
    {
        Outer obj=new Outer();
        obj.method1();
    }
}

class Outer
{
    void method1()
    {
        class Inner
        {
        }
    }
}

我想知道,Inner 类什么时候会被 ClassLoader 加载。 它是在调用 method1() 时加载的,还是在我们创建它的实例时加载的?并且类 Inner 没有在 method1() 中执行任何操作,它是一个空类。另外,我想知道,上例中如何创建内部类的实例?

【问题讨论】:

标签: java class nested


【解决方案1】:

Outer.Inner 将在第一次被另一个类引用为变量类型、方法参数类型、方法返回类型、超类类型、类型参数绑定或初始值设定项或静态方法的目标类型时被加载,或者加载静态变量引用的宿主类。在您的示例中,我希望它永远不会被加载。

另外,我想知道,在上面的例子中,如何创建内部类的实例?

正如它所写的,类Outer.Inner 只能在方法Outer.method1() 中访问,因此它只能在该方法中被实例化。在那里,您可以使用new Inner()。如果您希望它可以从其他地方实例化,则将其声明移出方法主体:

class Outer
{
    class Inner
    {
    }

    void method1()
    {
    }
}

无论如何,这对于 named 内部类来说是更好的形式。 Outer.Inner 何时加载或是否加载都不会改变。

通过该更改,您可以通过new Inner() 的形式在Outer 的构造函数或实例方法中的任何位置实例化Outer.Inner。但是,如果您想从不同的类中实例化一个,或者在类Outer 的静态方法中实例化一个,那就有点棘手了。要意识到的重要一点是Outer.Inner 的每个实例都需要Outer 的关联实例。这是在Outer 的实例方法中执行实例化时从上下文确定的,但如果在没有这样的上下文的情况下执行,则语法为:

    public static void main(String args[])
    {
        Outer obj=new Outer();
        Outer.Inner inner = obj.new Outer.Inner();
    }

【讨论】:

    【解决方案2】:

    引用 JLS 的Section 12.4.1

    一个类或接口类型 T 将在 以下任何一项的第一次出现:

    T 是一个类,并创建了一个 T 的实例。

    T 声明的静态方法被调用。

    分配了一个由 T 声明的静态字段。

    使用了由 T 声明的静态字段,并且该字段不是常量 变量(第 4.12.4 节)。

    T 是顶级类(第 7.6 节)和断言语句(第 14.10 节) 执行词法嵌套在 T(第 8.1.3 节)中。

    因此,一个类(不管是否是嵌套类)将遵循相同的规则。在您的特定情况下,Inner 在创建类的实例之前不会被加载。

    要回答您的第二个问题,您只能在method1 内创建Inner 的实例,因为Inner 是一个方法本地类,其范围仅限于method1

    void method1()
    {
    
        class Inner
        {
            public Inner()
            {
                System.out.println("inner()");
            }
        }
    
        Inner inner = new Inner();
    }
    

    【讨论】:

      【解决方案3】:

      要实现内部类,无论如何你都需要对象。如果你这样调用method1(),内部类永远不会被调用。

      但是如果你在 method1() 或 public Outer() 构造函数中定义了一些对象,你可以从内部类中得到结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多