【问题标题】:How can an anonymous class have arguments?匿名类如何有参数?
【发布时间】:2011-12-06 15:59:41
【问题描述】:

我不是 java 人,但我继承了一些需要修补的代码。我将源代码拉入netbeans,但出现错误:匿名类实现接口;不能有参数。

代码如下:

Executor background = Executors.newSingleThreadExecutor();
Runnable mylookupThread = new Runnable(FilePath, SearchIndex)
{
    public void run()
    { MainWindow.this.processFile(this.val$FilePath);
        Thread t = new Thread(new lookupThread(MainWindow.arrFile, true, false, this.val$SearchIndex));
        t.setName("Lookup");
        t.setPriority(10);
        t.start();
    }
};
background.execute(mylookupThread);
Executor statusThread = Executors.newSingleThreadExecutor();
Runnable myStatusThread = new Runnable()
{
    public void run()
    { MainWindow.this.updateStatus();
    }
};
statusThread.execute(myStatusThread);

错误出现在第二行。救命?!?

【问题讨论】:

    标签: java class interface anonymous


    【解决方案1】:

    mylookupThread 设为单独的类,使其成为实例并将其传递给Executor

    class LookupTask implements Runnable {
        private final String filePath, searchIndex;
        LookupTask(String filePath, String searchIndex) {
           this.filePath = filePath;
           this.searchIndex = searchIndex;
        }
    
        public void run() { ... } 
    }
    ...
    background.execute(new LookupTask(filePath, searchIndex));
    

    另一种方法是使filePath, searchIndex final:

    final String filePath = ...
    final String searchIndex = ...
    Executor background = Executors.newSingleThreadExecutor();
    Runnable mylookupThread = new Runnable() {
        public void run() { MainWindow.this.processFile(filePath);
            Thread t = new Thread(new lookupThread(MainWindow.arrFile, true, false, searchIndex));
            t.setName("Lookup");
            t.setPriority(10);
            t.start();
        }
    };
    background.execute(mylookupThread);
    

    【讨论】:

      【解决方案2】:

      new -interface- 形式的匿名类隐式扩展了 Object。您必须使用constructors for Object 之一。只有一个 - 无参数构造函数。

      【讨论】:

      • 每个 Java 类都扩展 Object.
      • 是的,但不是每个类都隐式地直接扩展 Object。如果它是明确的,例如lookupThread = new Object ( FilePath , SeatchPath ) { ... } 为什么不允许使用参数会更明显。
      • 啊,但你不是在创建一个对象——你是在创建一个匿名类的实例。对无参数构造函数的限制不是来自 Object 类,而是来自语言定义本身。即使明天将新的构造函数添加到 Object 中,它也会保留。见java.sun.com/docs/books/jls/third_edition/html/…
      • 如果我可以挥动我的魔杖并向 Object 类添加一个公共 Object ( int val ) 构造函数,那么为什么我不能创建一个像 Object obj = new Object ( 5 ) ; 这样的匿名类的实例?语言定义所指的匿名构造函数。
      • 我完全错了。你是对的。我自己引用的链接准确地指定了您描述的行为。 +1。
      【解决方案3】:

      @Victor 是对的,您可以创建另一个类。您还可以在 final 的匿名类中使用变量。像下面这样的东西会起作用。

      Executor background = Executors.newSingleThreadExecutor();
      private final FilePath filePath = ...;
      private final String searchIndex = ...;
      Runnable mylookupThread = new Runnable() {
          public void run() {
              MainWindow.this.processFile(filePath);
              Thread t = new Thread(new lookupThread(MainWindow.arrFile, true, false,
                 searchIndex));
              t.setName("Lookup");
              t.setPriority(10);
              t.start();
          }
      };
      

      顺便说一句。在执行器中执行的线程的Runnable 内创建线程有点奇怪。不知道为什么不直接生成 LookupThread 并完全删除匿名类。

      【讨论】:

        【解决方案4】:

        这是问题所在(如你所说:)

        Runnable mylookupThread = new Runnable(FilePath, SearchIndex) { ...
        

        我们正在动态定义一个类,并且该类实现了Runnable 接口。当您使用此语法时,括号中的项目旨在作为超类的构造函数参数。因为Runnable是一个接口,而不是一个类,它根本没有构造函数,所以肯定没有带参数的。

        也就是说,无论它们应该是什么,它们都不会在匿名类的主体中使用,因此大致而言,您只想完全删除括号内的内容。

        【讨论】:

          猜你喜欢
          • 2011-07-03
          • 2011-10-01
          • 2017-04-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-16
          • 1970-01-01
          相关资源
          最近更新 更多