带有静态内部类的Java新关键字

问题描述 投票:2回答:4

我知道以前曾问过这个问题,但是大多数关于某个库都非常具体。给出的答案并没有真正向我解释发生了什么。

这就是为什么我在这里设置一个非常简单的测试方案并尝试摆弄它的原因,但是仍然存在一些问号!Online Java Example

简单的代码由两个文件组成:

Main.java

public class Main
{
    public static void main(String[] args) {
        // this works, and inner1 and inner2 seem to be new instances
        Outer.Inner inner1 = new Outer.Inner();
        Outer.Inner inner2 = new Outer.Inner();
        inner1.setName("Mario");
        inner1.say();
        inner2.setName("Luigi");
        inner2.say();

        // if Inner is not a public static class this gives this error:
        // error: an enclosing instance that contains Outer.InnerNoStatic is required
        Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();
    }
}

Outer.java

public class Outer {
    public static class Inner {
        private String name;

        public void say() {
            System.out.println("Hi " + name);
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    public class InnerNoStatic {
        public void say() {
            System.out.println("Hi from InnerNoStatic");
        }
    }
}

因此,即使Inner类是用静态声明的,我们仍然创建了两个新实例,分别称为inner1和inner2。为什么叫静态呢?

反过来,如果我删除了静态变量,如InnerNoStatic所示,我将如何获取该类的实例?

java class static new-operator
4个回答
1
投票

[static在此处指示相对于Inner如何使用InnerNoStaticOuter

因为InnerOuter中是静态的,所以它没有绑定到Outer的任何特定实例(一如既往,静态成员属于该类,而不属于该类的任何特定实例)。这就解释了如何编译:

Outer.Inner inner1 = new Outer.Inner();

InnerNoStatic,但是,是一个实例成员(也就是说:如果它不是静态的,它将绑定到给定的成员)。这就解释了为什么编译器会在这里引发错误:

Outer.InnerNoStatic inner3 = new Outer.InnerNoStatic();

因为InnerNoStatic必须绑定到Outer的实例,所以需要使用这样的实例来创建inner3

Outer.InnerNoStatic inner3 = new Outer().new InnerNoStatic(); //note the calls

您也可以使用现有实例。

Outer outer = new Outer();
Outer.InnerNoStatic inner3 = outer.new InnerNoStatic();

在这两种情况下,都使用Outer实例来构建InnerNoStatic实例(没有变量指向使用Outer创建的new Outer().new InnerNoStatic()对象)


注意:很容易将new Outer.Inner();new Outer().new Inner();混淆。它们没有做相同的事情(前者中的“外部”基本上起着命名空间的作用,而后者中的new Outer()创建了Outer对象)。也就是说,前者有一个构造函数调用(Inner()),而后者有两个构造函数调用(Outer()Inner())。


1
投票

因此,即使Inner类是用静态声明的,我们仍然创建了两个新实例,分别称为inner1和inner2。为什么叫静态呢?

static表示嵌套类具有更多的独立性。它主要是为了提高封装性,可读性,可维护性而设计的,这是对类进行逻辑分组的好方法。

反过来,如果我删除静态对象,如InnerNoStatic,我将如何获取该类的实例?

语法有点不同,因为您需要Outer的实例。

Outer.InnerNoStatic inner3 = new Outer(). new InnerNoStatic();

1
投票

因此,即使Inner类是用静态声明的,我们仍然创建了两个新实例,分别称为inner1和inner2。为什么叫静态呢?

“静态”内部类的对象不与其封闭类的对象绑定,与非“静态”内部类相反。拥有一个“静态”内部类而不是将其移到“顶级”是一种向用户发出信号的便捷方式,可向用户发出该内部类的对象与外部类没有太多用处的信息,类似于e。 G。 Map.Entry

反过来,如果我删除静态对象,如InnerNoStatic,我将如何获取该类的实例?

例如

public class Outer {

  private InnerNoStatic innerNoStatic = new InnerNoStatic();

  public InnerNoStatic getInnerNoStatic () {
    return innerNoStatic;
  }
  // ...

Outer.InnerNoStatic innerNoStatic = new Outer().getInnerNoStatic();

1
投票

非静态内部类始终具有对相应外部类的引用。结果,此类只能由外部类实例化。

相反,如果可见性允许,则静态内部类不引用外部类,并且可以由任何其他对象创建。这与静态方法的行为非常相似,后者不需要调用对象实例。

© www.soinside.com 2019 - 2024. All rights reserved.