Java中的函数回调也是一个匿名类吗?

时间:2014-11-24 14:16:44

标签: java

例如,在此代码段中:

c.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
    System.out.println("Mouse entry event: " + e
                       + " on button: " + buttonLabel);
  }
});

addMouseListener括号内的代码块是否声明了MouseAdapter()的匿名类,然后整个内容被称为'function callback',或者我是否混淆了这些条款?有什么区别?

2 个答案:

答案 0 :(得分:8)

没有

您可以在Java中以多种方式实现回调,匿名类是一种常见的方式,尤其是在Java 8之前。

在OO中,回调与名为 Hollywood Principle 的原则相关:“不要打电话给我们,我们会打电话给你”。检查here以获取有关java中回调的更多信息。

在Java中,我们只有类/对象,因此,回调将始终使用Java中的对象实现。因此,我认为我们不应该在Java中将其称为“函数回调”,相反,回调对象可能更合适。

我们将一个回调对象传递给另一个对象,以便当该对象认为是时候时,该对象可以调用回调对象上的某个特定方法。在您的情况下,您将MouseAdapter实例传递给c。当输入鼠标时,c将调用传递的mouseEntered实例的方法MouseAdapter(c认为是时间)。所以,我们没有明确地调用相对于鼠标输入的c'method,如:

while(true){
    if(mouce_entered){
         mouseEntered();
     }
    wait_for_mouseentered_event();
}

相反,c执行所有这些工作,我们只需要将回调对象传递给他,让c控制逻辑流程。

实际上,实现此回调的第一种方法是声明一个类扩展MouseAdapter

public class YourMouseListener extends MouseAdapter() 
{
    public void mouseEntered(MouseEvent e) { ... } 
} 

然后创建一个实例并传递给它:

  c.addMouseListener(new YourMouseListener());

2.为了最小化声明的代码和类,Java允许您使用匿名类来实现回调,如:

c.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
    System.out.println("Mouse entry event: " + e
                       + " on button: " + buttonLabel);
  }
});

3.在Java 8中,我们有lambda表达式,我们可以将一些匿名类替换为更简洁的lambada表达式,但这仅限于函数接口,它只有一个方法。

//Old way:
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("The button was clicked using old fashion code!");
    }
});

//New way:
button.addActionListener( (e) -> {
        System.out.println("The button was clicked. From lambda expressions !");
});

答案 1 :(得分:0)

是的,它会创建一个匿名类。编译代码后,您甚至可以看到类文件。这是因为Java中没有“第一类”函数(或lambdas)(至少在Java 8之前,但它们仍然可能创建匿名类)。