2014-11-24 29 views
2

例如,在这个代码片段:Java中的函数回调也是匿名类吗?

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

addMouseListener声明了一个匿名类的MouseAdapter()括号,然后整个事情被称为“function callback”里面的代码块,还是我混淆的术语?有什么不同?

+1

是它的一个匿名类和它的一个监听器。 [回调和监听器之间有区别](http://programmers.stackexchange.com/questions/84732/what-is-the-difference-between-callbacks-and-listeners)。 – Sikorski 2014-11-24 14:21:20

回答

6

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

在面向对象,回调是相对于所谓的Hollywood Principle原则: “不要打电话给我们,我们会打电话给你”。有关在java中回调的更多信息,请查询here。在Java中,我们只有类/对象,因此,回调将始终使用Java中的对象实现。因此,我认为我们不应该在Java中将其称为“函数回调”,相反,回调对象可能更合适。

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

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

相反,c做这一切工作,我们只需要一个回调对象传递给他,让c控制逻辑流程。

1.So,实际上,为了实现这个回调的第一种方式是声明一个类扩展MouseAdapter

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

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

c.addMouseListener(new YourMouseListener()); 

2.To最小化代码和类声明,Java使您可以使用匿名类来实现回调,如:

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

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

//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 !"); 
}); 
0

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

+0

那么有什么区别?例如,您可以获得不是匿名类的函数回调吗? – 2014-11-24 14:27:49

+0

在Java中没有区别。 Java 8的语法糖使得这个更好,但它仍然会创建一个类。 – pablochan 2014-11-24 14:29:56

+1

当然,您可以创建不是匿名类的函数回调函数。简单地创建显式类,如下所示:'class MyMouseListener extends MouseAdapter(){public void mouseEntered(MouseEvent e){...}} c.addMouseListener(new MyMouseListener());'作为Java程序员,我们倾向于只使用显式如果存在(有些主观的)重用的好机会的话。 – 2014-11-24 14:36:22