例如,在此代码段中:
c.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse entry event: " + e
+ " on button: " + buttonLabel);
}
});
addMouseListener
括号内的代码块是否声明了MouseAdapter()
的匿名类,然后整个内容被称为'function callback
',或者我是否混淆了这些条款?有什么区别?
答案 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
控制逻辑流程。
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之前,但它们仍然可能创建匿名类)。