【问题标题】:Why have public static class inside a class为什么类中有公共静态类
【发布时间】:2025-12-03 07:35:01
【问题描述】:

我正在浏览一些代码,我看到了这个:

public class A {
    public A(SomeObject obj) {
      //Do something
    }
    //Some stuff
  public static class B {
    //Some other stuff
  }
}

我想知道,既然内部类是public,为什么它是嵌套的而不是单独的类? 另外,我可以在这里执行此操作:new A.B(SomeObject) 吗?我觉得这违背了静态类的目的,但我也看到了这个实现,所以很想知道。

【问题讨论】:

    标签: java nested-class


    【解决方案1】:

    我想知道,既然内部类也是公共的,为什么要将它作为嵌套类而不是单独的类?

    这真的是要问编写课程的人。虽然它可以允许外部类充当“迷你命名空间” - 如果嵌套类在外部类的上下文中有用,这似乎是合理的。它表明两个类之间故意紧密耦合。我最常在构建器模式的上下文中看到这一点:

    Foo foo = new Foo.Builder().setBar(10).build();
    

    在我看来,将Foo.Builder 嵌套在Foo 中而不是作为可能称为FooBuilder 的对等类是有意义的。

    请注意,与仅不相关的类相比,它还提供了一些可见性差异。

    另外,我可以在这里执行此操作:new A.B(SomeObject) 吗?

    没有,因为 B 没有带有 SomeObject 参数的构造函数 - 只有 A 有(在您给出的示例中)。

    我觉得这违背了静态类的目的

    您应该尝试准确地弄清楚您认为静态类的目的是什么,以及这会以什么方式破坏该目的。目前,这种说法过于模糊,无法进行实际讨论。

    【讨论】:

      【解决方案2】:

      你会有一个这样的内部类

      • 您可以保留一个仅存在以支持封装的外部类的类。
      • 您希望能够访问外部类或其他嵌套类的private 成员。
      • 您想要一个带有静态字段的嵌套类(我知道这是一个不充分的理由;)
      • 您有一个具有非常通用名称的类,例如 LockSync,您不希望与同一包中的类使用的其他同名类混合。

      我可以在这里执行此操作:new A.B(SomeObject) 吗?

      你可以。

      我觉得这违背了静态类的目的

      这需要习惯,但一旦你开始,你可能无法将整个程序变成一个 file.java ;)

      【讨论】:

        【解决方案3】:

        1.static inner 类称为Top-Level 类。

        2. 这个static class 具有直接访问到其外部类静态方法和变量。

        3.您需要以这种方式从外部初始化static Inner class...

            A a = new A();
            A.B b = new A.B();
        

        4. new A.B(SomeObject) 不会工作...因为你没有构造函数SomeObject 作为参数...

        5. 但是当 Inner 类是 Non-static 时,它会隐式引用 Outer 类。

        6.外部类和内部类可以扩展到不同的类

        7.interface's method 可以使用内部类以不同或相同的方式多次实现

        【讨论】:

          【解决方案4】:

          这种模式经常与建造者模式一起使用。它不仅明确了类与其构建器之间的关系,而且隐藏了丑陋的构建器构造器/工厂,使构建器更具可读性。例如,如果您需要构建的对象具有可选属性而不是可选属性。

          public class AnObject {
             public static class AnObjectBuilder {
          
                 private AnObject anObject;
          
                 private AnObjectBuilder() {
                 }
          
                 private void newAnObjectWithMandatory(String someMandatoryField, ...) {
                     anObject = new AnObject(someMandatoryField,...)
                 }
          
                 public AnObjectBuilder withSomeOptionalField(String opt) {
                     ...
                 }
             }
          
             public static AnObjectBuilder fooObject() {
                  return (new AnObjectBuilder()).newAnObjectWithMandatory("foo")
             }
          
             public static AnObjectBuilder barObject() {
                  return (new AnObjectBuilder()).newAnObjectWithMandatory("bar")
             }
          }
          

          这样,客户端代码必须首先调用 AnObjectBuilder 类上的静态方法,然后才能使用可选的构建器方法:

          AnObject.fooObject("foo").withSomeOptionalField("xxx").build(); 不创建构建器对象。

          非常易读:)

          【讨论】:

            【解决方案5】:

            我想知道,既然内部类是公共的,为什么要将它作为嵌套类而不是单独的类?

            看看这个帖子:Why strange naming convention of "AlertDialog.Builder" instead of "AlertDialogBuilder" in Android

            另外,我可以在这里执行此操作:new A.B(SomeObject) 吗?

            (更新)不,你不能这样做,因为 B 没有请求 SomeObject 的构造函数。

            我希望这会有所帮助。

            【讨论】:

            • 您的链接当前指向最后一个答案。我建议使用此链接 *.com/questions/11810345/…
            • 根据下面给出的其他答案,我认为您对new A.B(SomeObject) 的回答是错误的,这实际上是有道理的,因为静态类没有构造函数
            【解决方案6】:

            我想知道,因为即使内部类也是公开的,为什么要将它作为 嵌套而不是单独的类?

            允许它的简单原因是包装方便。

            Static nested class in Java, why?

            http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

            是的,您可以新建A.B(SomeObject)。但你不必相信我的话,试试看。

            【讨论】:

              最近更新 更多