声明匿名内部类

4
rb.addActionListener(new ActionEvent(ae) {
   public void actionPerformed(ActionEvent ae) {
     nowCall(ae);
    }
});

另一种方式

Thread th=new Thread(Runnable r) {
  public void run() {
    // do something
  }
};

// notice the ending of above 2 snippets

我非常困惑这两个东西。似乎没有确切的模式来声明匿名内部类。

请解释一下匿名内部类的语法。


类可以是匿名的或内部的。您有匿名类的示例。内部类是一种非静态嵌套类,它具有名称。 - Peter Lawrey
2
@Peter,Oracle 不同意你的观点。请参阅本地和匿名内部类 - Isaac Truett
6个回答

8
据我所见和测试,第二种方式是无效的。
更常见的方法是创建一个新的Runnable实现:
Thread th=new Thread(new Runnable() {
  @Override
  public void run() {
    // This implements Runnable.run
  }
});

现在,您可以重写普通线程的run方法:

Thread th=new Thread() {
  @Override
  public void run() {
    // This overrides Thread.run
  }
};

...但是个人更喜欢在创建线程时单独指定Runnable

现在你注意到的区别只是表达式是否用作参数(例如传递给addActionListener方法或Thread(Runnable)构造函数),或者直接分配给变量。将整个new TypeName() { ... }视为单个表达式,这只是以下两种方式之间的区别:

Thread th = expression;

并且

Thread th = new Runnable(expression);

@ Jon Skeet 在你的第一个片段中,runnable接口是否被实现在run方法中? - saplingPro
@Meprogrammer:是的,那是Runnable中唯一的方法。 - Jon Skeet
@ Jon Skeet 在这里的所有构造函数中,您的第一个示例中使用了哪个线程的构造函数? - saplingPro
@Meprogrammer:第二个,它只有一个类型为Runnable的参数。 - Jon Skeet
@ Jon Skeet,我不理解“how”。你能解释一下吗? - saplingPro
@ Jon Skeet,我理解第二个构造函数是“参数将接受实现了Runnable接口的类的实例”。如果正确的话,您能否与您的代码片段建立关系? - saplingPro

2

[...] 请注意上面两个代码片段的结尾

你第一个例子中的括号)仅仅是对该语句的终止。

rb.addActionListener(
(即,您的两个示例具有不同的结尾,因为一个是赋值语句的右侧,

Thread th = ... ;

而另一个是方法调用的参数

...addActionListener( ... );

创建匿名类的语法非常简单:)
new SomeClassOrInterface() {
    // implementation goes here
}

正如您所看到的,这是您两个示例的模式。


来自匿名类(Java in a Nutshell)

3.12.3. New Syntax for Anonymous Classes

We've already seen examples of the syntax for defining and instantiating an anonymous class. We can express that syntax more formally as:

new class-name ( [ argument-list ] ) { class-body }

or:

new interface-name () { class-body }

此外,你在第二个示例中存在拼写错误。它可能应该是 new Thread() { ...new Thread(r) { ...(尽管在后一种情况下,重写的方法将不会被调用)。


2

第一种情况是将参数传递给方法,而第二个示例是将其存储在本地变量中,这是它们之间的区别。

因此,您不能真正将两个示例进行比较。


1
你不能直接覆盖一个方法。实际上,两者都是匿名内部类,在它们的声明中没有任何区别。 - biziclop
两者都是匿名的,没有区别。 - Nishant
当然,这是一个匿名类。你能告诉我这个Thread的子类的名称吗? - aioobe
好的,我明白了。我会更改答案。 - RoflcoptrException

0
  1. 实例化新的匿名类并将对象传递给 addActionListener 方法。

  2. 实例化新的匿名类并将对象分配给本地变量 th


0

它们是一样的。您可以在声明后,在分号之前放置匿名类:

new ActionEvent(ae) {class details, methods etc} ;

Thread(Runnable r) { public void run() { // do something }} ;

在这两种情况下,您都创建了一个新的类实例,在第一个示例中,您将其用作方法的参数,在第二个示例中,您将其分配给变量。


0

区别在于您可以将接口实现为匿名内部类或扩展类。在您的示例中,两者都是扩展类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接