【问题标题】:What is the purpose of defining an inner class within a static method?在静态方法中定义内部类的目的是什么?
【发布时间】:2013-10-22 19:25:59
【问题描述】:

我正在阅读“Head First Java”一书,其中提到内部类实例必须绑定到外部类实例,我已经知道了,但有一个例外:

一种非常特殊的情况——在静态方法中定义的内部类。但 你可能会在你的整个 Java 生活中没有遇到过任何一种 这些。

我很确定最后一条语句确实是正确的,但是如果编译器允许它发生,则意味着它的存在是有原因的,否则它将是非法的 Java。有人可以给我举个例子说明这在哪里有用吗?

【问题讨论】:

  • 可以是匿名内部类吗?因为有很多这样的。
  • 这是一个本地类,JLS #14.3,而不仅仅是一个内部类。
  • @EJP 但它一个内部类,所以它符合问题的标准。

标签: java oop static inner-classes


【解决方案1】:

它可能很特别,也可能不是。

您正在查看方法中可用的本地类:

class Foo {
    static void bar(){
       class MyRunnable implements Runnable {
           public void run() {
               System.out.println("No longer anonymous!");
           }    
        };
       Thread baz = new Thread(new MyRunnable());
    }

}

我见过匿名内部类的用法,例如:

class Foo {
    static void bar(){
        Thread baz=new Thread(new Runnable(){
            public void run(){
                System.out.println("quux");
            }
        }
    }
}

这在技术上是一个内部类(虽然是匿名的)并在静态方法中定义。我个人会创建一个实现 Runnable 的静态嵌套类并执行以下操作:

baz = new Thread(new MyRunnable());

其中MyRunnable 定义为:

class Foo {
    static void bar(){
       // SNIP
    }
    static class MyRunnable implements Runnable {
        public void run() {
            System.out.println("No longer anonymous!");
        }    
    }
}

【讨论】:

  • 如果您将MyRunnable 移动到bar 中,您将获得与 fedeetz 感兴趣的完全相同的场景。
  • 编译不了,把static class MyRunnable改成class MyRunnable
  • @MiserableVariable 对不起,我个人对本地课程并不精通。
  • 有趣。我问这个是因为我在任何项目中都没有接近过需要这样的东西。
  • 看我的回答,希望它能解释
【解决方案2】:

有些人认为任何可以是静态的方法应该是静态的。对于这样的人来说,班级的内在美并没有太大的意义。

【讨论】:

    【解决方案3】:

    这是一个虚构的静态方法中的内部类示例。可以说是

    1. 它不需要在静态方法之外声明,因为其他地方不需要它
    2. 它应该是一个命名类(即不是匿名的),因为它被多次使用

      class Race {
          public static void main(String[] args) throws Exception{
              class Runner implements Runnable {
                  final String name;
                  long time = -1;
                  Runner(String name) { this.name = name; }
                  public void run() {
                      try {
                          long start = System.currentTimeMillis();
                          time = -2;
                          System.out.printf("Start %s\n", name);
                          for (int i = 0; i < 10; i++) {
                              Thread.sleep(1000);
                          }
                          System.out.printf("End %s\n", name);
                          this.time = System.currentTimeMillis() - start;
                      } catch (InterruptedException e) {
                          time = -3;
                      }
                  }
                  long time() { return time; }
              }                
              Runner r1 = new Runner("One");
              Runner r2 = new Runner("Two");
              Thread one = new Thread(r1);
              Thread two = new Thread(r2);
              one.start();
              two.start();
              one.join();
              two.join();
              System.out.printf("One: %s, Two: %s\n", r1.time(), r2.time());
              System.out.printf("%s wins\n", r1.time() < r2.time() ? "one" : "two");
          }
      }
      

    【讨论】:

    • 感谢您的示例!
    【解决方案4】:

    我不知道完整的上下文,但闭包(即 Guava 的 Function 实现)和实用程序类中定义的实现可能就是一个例子。

    但是,搜索了一段时间,并没有在 Guava 本身中找到匿名闭包的例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 2014-07-13
      • 1970-01-01
      相关资源
      最近更新 更多