10

Kushal Paudyal 询问在 Java 中可以嵌套多深的内部类。共识是,虽然语言本身没有限制,但底层操作系统和文件系统可以。

你有没有发现两层或多层嵌套内部类有用的案例?

更新 (11/28):如果您考虑枚举类,第二层嵌套可能是有意义的。在最近的一些重构中,我简要地有一个外部类(一个 HTTP 客户端)、一个内部类(一个内存缓存)和一个内部类内部的枚举类(用于缓存驱逐策略)。这似乎没问题,但就@Thorbjørn 而言,我继续从 HTTP 客户端类中提取缓存类及其内部枚举。

4

6 回答 6

5

不我没有。

类中的类的标准示例是 Builder,其中您有一个子类来帮助创建一个适当的实例,给定许多可能的配置方法。

就个人而言,我认为嵌套类的更复杂情况是需要重构的代码的极好示例。

于 2009-11-23T21:45:06.583 回答
3

我个人还没有遇到过证明需要不止一个的案例。我可以预见两个可能有用的情况。然而,我很难想象超过两个。

我想象的例子是 Java GUI 代码。在某些情况下,将类嵌套在已经嵌套的 ActionListener 中可能很有用。

于 2009-11-23T21:29:48.350 回答
3

如果您从某些数据生成代码,嵌套类可能是避免名称冲突的好方法。

于 2009-11-23T23:04:20.393 回答
2

我看到了嵌套类级别数的用法。

有一台名为 Tandem(HP)的遗留机器,它最初运行 COBOL/C 代码。后来的“补丁”也使该机器也可以运行java。COBOL 的变量结构自然是多级的(甚至 5 级也是常见的情况),所以为了让 java 调用 COBOL 服务器,java 类也是多级的,以简化它们之间的数据转换.

我同意这是一个非常罕见的情况,但无论如何......

于 2009-11-23T23:33:39.850 回答
2

我知道我正在回收一个旧线程,但这对我来说是新的:)

我们为我们的 POJO 使用多个级别来反序列化 JSON(使用 Jackson)。这是我们可能从 RESTful Web 服务返回的 JSON 的一个小示例(组成):

{ success: true, response: {
    sales: { item: "123", sales: 3, returns: 1 }, 
    inventory: { item: "567", qty: 100 } 
  }
}

我们曾经将 POJO 设置为:

public class Json1 {
  private boolean success;
  private JsonResponse response;
}
public class Json1Response {
  private JsonResponseSales sales;
  private JsonResponseInventory inventory;
}
public class Json1ResponseSales {
  private String item;
  private int sales;
  private int returned;
}
public class Json1ResponseInventory {
  private String item;
  private int qty;
}

我们有很多这样的东西,我们可能提出的每个 Web 服务请求都有一个 POJO。这种布局给了我们一些琐碎的疑问:

  1. 请注意,这个相对简单的示例为我们提供了四个类文件来跟上。现在将其乘以 100,然后将“难度系数”乘以 3,以说明大多数 JSON 比这更混乱的事实。数以千计的文件。

  2. 字段名称在各处重复使用,并且相同的字段名称可能具有不同的内容,具体取决于哪个 Web 服务。(想象一下,数量可能会从一个 Web 服务返回为字符串,从另一个返回为 int,然后将其乘以 100。)

由于这些东西以父/子关系联系在一起,我们决定改用这种布局。

public class Json1 {
  private boolean success;
  private JsonResponse response;

  public class Json1Response {
    private JsonResponseSales sales;
    private JsonResponseInventory inventory;

    public class Json1ResponseSales {
      private String item;
      private int sales;
      private int returned;
    }

    public class Json1ResponseInventory {
      private String item;
      private int qty;
    }
  }
}

在这种情况下,我嵌套了两层,但可能更多。也许高达四深。

于 2015-08-14T15:26:12.330 回答
1

当然 - 这有时是有效的。我几分钟前刚做了一些。

例如,在我编写的一些测试代码中,我想设置一些样板来处理运行多个可调用对象。样板文件需要创建可调用代码块的多个实例。在此示例中,我创建了一个工厂实例以传递给 threadedTest,并且该工厂创建了新的可调用对象。

@Test public void testXXXXXXXX() throws Throwable {
    threadedTest(new CallableFactory() {
        @Override public Callable<Request> create() {
            return new Callable<Request>() {
                // might have state
                @Override public Request call() throws Exception {
                    // do the steps for this test
                    return ...;
                }};
        }});
}

比创建两个新类(其中一个只创建另一个类)要简洁得多。当然,在您习惯这种风格之前,这里的可读性会受到影响,不过......

如果你将它与模板方法结合起来来控制事务或数据库连接/关闭,这可能会达到三个深度。(我有一些这样的代码;如果你这样做,请确保你在评论中写了一个虚拟样本并很好地解释了结构)

于 2009-11-23T23:01:55.430 回答