代码之家  ›  专栏  ›  技术社区  ›  Jim Ferrans

将Java内部类嵌套到一层以上是否合理?

  •  10
  • Jim Ferrans  · 技术社区  · 16 年前

    how deep you can nest inner classes 在Java中。大家一致认为,虽然语言本身没有限制,但底层操作系统和文件系统可能会受到限制。

    您是否发现过两个或两个以上级别的嵌套内部类有帮助的情况?

    更新(11/28):如果考虑EnUM类,第二级嵌套是有意义的。在最近的一些重构过程中,我简单地使用了一个外部类(HTTP客户端)、一个内部类(内存缓存)和一个内部类(用于缓存逐出策略)的枚举类。这似乎没什么问题,但就@Thorbjrn而言,我继续从HTTP客户机类中提取缓存类及其内部枚举。

    6 回复  |  直到 9 年前
        1
  •  5
  •   Thorbjørn Ravn Andersen    16 年前

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

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

        2
  •  3
  •   Daniel Bingham    16 年前

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

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

        3
  •  3
  •   Jimmy    16 年前

        4
  •  2
  •   Jim Ferrans    16 年前

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

        5
  •  2
  •   bobanahalf    10 年前

    我知道我在回收一根旧线,但它对我来说是新的:)

    我们对POJO使用多个级别来反序列化JSON(使用Jackson)。下面是我们可能从RESTful web服务中获得的JSON的一个小示例(由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;
    }
    

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

    2. 字段名在各地重复使用,相同的字段名可能有不同的内容,这取决于哪个web服务(想象一下,数量可能从一个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;
        }
      }
    }
    

        6
  •  1
  •   Scott Stanchfield    16 年前

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

    @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 ...;
                    }};
            }});
    }
    

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

    如果将其与模板方法相结合以控制事务或数据库连接/关闭,则可能会导致三个深度(我有过这样的代码;如果你这样做了,确保在你的评论中写一个虚拟的例子,并解释好结构)