【问题标题】:What benefit do method-local inner classes provide in Java?方法局部内部类在 Java 中提供什么好处?
【发布时间】:2011-04-04 19:39:20
【问题描述】:

我刚刚通读了SCJP book 中关于方法局部内部类的章节,我真的很难想出它们的实际用途。

我一直有这样的印象,即方法应该尽可能小且特定于它们的任务 (OrthogonalityIIRC),因此即使是最简单的内部类也会创建笨重的方法。

任何人都可以建议方法本地内部类的良好实际用法吗?到目前为止,感觉好像我可能必须纯粹为了通过考试而理解它们,而不是为了在日常编码中使用。

干杯

【问题讨论】:

  • 它们通常用于实现回调方法。
  • 到目前为止,我只使用过一次:我需要一个合适的键类用于方法中的临时 HashMap。
  • 真实世界方法的本地内部类用法在这里:stackoverflow.com/a/14900700/82609

标签: java inner-classes scjp


【解决方案1】:

在大多数情况下(例如,对于动作侦听器、可运行对象等),您会使用匿名类而不是方法本地命名类。

但是有一件事情是命名类可以做而匿名类不能做的:实现多个接口,或者扩展一个类和接口。此外,您可以创建多个此类的对象(不使用循环)。

【讨论】:

  • "另外,您可以创建多个此类的对象(不使用循环)。" - 你当然可以。即使跨多次调用定义类的方法,类仍然是一样的。
  • 虽然这证明了它为什么存在的理由(实现多个接口),但它并不表示实际用途。是否有理由在方法中声明类?我还没有看到任何来自开放 jdk 的示例
【解决方案2】:

我会说更好的封装是好处。

【讨论】:

    【解决方案3】:

    当您尝试执行“功能性”操作或将代码传递给稍后调用的另一个对象时,方法本地内部类很有用。在大多数情况下,像这样的类只被调用或使用一次,因此无需在其他地方定义它并强迫读者去寻找它。未来的 Java 版本可能会用“闭包”替换这些类型的内部类的大多数用例。

    常见的情况是您正在编写一个调用其他方法的事件侦听器或启动一个新线程。

    【讨论】:

    • 使用匿名类而不是方法本地命名类更好。
    【解决方案4】:

    本地类允许从父类中取出逻辑并将其对象化。这会从它不属于的地方删除功能并将其放入自己的类中。但是如果这个新对象只需要很短的时间,只需要一个代码块的持续时间呢?嗯,这就是本地类适合的地方。

    【讨论】:

      【解决方案5】:

      我想到了Runnable 实现传递给线程:

      Thread t = new Thread(new Runnable() {
         void run() {
            ...
          }
      });
      

      这是匿名类,任何匿名类也是内部的。

      【讨论】:

      • 但runnable不是方法本地内部类(它是一个普通的匿名内部类)
      【解决方案6】:

      很少使用局部类(方法局部内部类)。当方法内部需要任何重复的功能并且我们对创建类级方法不感兴趣(可能是因为我们可能不需要方法外部的此功能)时,它可能很有用,例如,假设 sum 和 mul 方法重复需要在我们的代码(任何特定方法)中,一种创建类级别方法并在需要时调用它们的方法,但是如果在此方法之外不再需要这些方法怎么办,在这种情况下,我们可能会考虑创建一个本地内部类并访问它仅在该方法中需要的 sum 方法,下面的示例

      class Outer {
          public void calculations() { 
              class Inner {
                  public int sum(int x, int y) {
                      System.out.println("sum : " + (x+y));
                      return x+y;
                  }
                  public int mul(int x, int y) {
                      System.out.println("multiplication : " + (x*y));
                      return x*y;
                  }
              }
              Inner i= new Inner();
      //some code...
              i.sum(10, 20);
      //some code...etc
              i.mul(30, 40);
              i.mul(14, 12);
              i.sum(10000, 20000);
      //some other code...
          }
      }
      public class TestClass {
          public static void main(String[] args) {
              new Outer().calculations();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2010-09-09
        • 2012-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-15
        • 1970-01-01
        • 2019-09-23
        • 2020-10-25
        相关资源
        最近更新 更多