需要澄清java中侦听器匿名类的概念

时间:2014-02-05 22:40:47

标签: java oop

我是java的新手。听众匿名内部类设计的目的是什么?我听说匿名类在java中用作监听器。并且没有人真正创建内部类甚至静态内部类。我不确定这意味着什么。有人可以解释一下这些概念吗?特别是这个监听器设计以及它是如何通过匿名类创建的。

提前谢谢。

3 个答案:

答案 0 :(得分:1)

匿名监听器通常看起来像这样:

myControl.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // Handle event
    }
});

使用内部类来实现相同的目标通常看起来像这样:

public void init()
{
    myControl.addActionListener(new MyActionListener());
}

private class MyActionListener implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        // Handle event
    }
}

现在考虑在更大的计划范围内这两者会是什么样子。匿名听众仍然在你添加它的地方。内部类可能完全位于源文件中的其他位置。使用一个好的IDE,可以最大限度地减少这种差异(例如成员浏览器),但是对于你将要使用的东西真的需要一个全新的类吗?

当然,根据您的应用程序的确切需求,单独的类实际上可能是更好的选择。例如,如果你有许多只有一点点不同的听众,你可以沿着这些方向构建一些东西:

public void init()
{
    myControl1.addActionListener(new MyActionListener("foo"));
    myControl2.addActionListener(new MyActionListener("bar"));
    myControl3.addActionListener(new MyActionListener("baz"));
}

private class MyActionListener implements ActionListener
{
    private String word;

    public MyActionListener(String word)
    {
        this.word = word;
    }

    public void actionPerformed(ActionEvent e)
    {
        // Handle event
        System.out.println(word);
    }
}

就静态类而言:在Java中,内部类可以标记为static,所有这一切都是为了防止它引用封闭类的实例。 (例如,MyProgram.MyStaticClass无法访问MyProgram的任何非静态成员,除非它创建{em>新 MyProgram实例。)这可能有助于分离关注点,但在听众方面并没有太大变化。

答案 1 :(得分:0)

这不是真的,没有人创建命名类来处理事件。然而,大多数时候事件处理程序实际上都是匿名类。原因是匿名类提供的代码更少,维护的文件更少,而且当您不必在许多小文件之间跳转时,更容易阅读代码。匿名类不应该太长(即不超过~20行代码),如果它们更长,它们应该转换为命名类。匿名类在少于8的java版本中很常见。在java 8中有Lambda表达式,它们类似于匿名类,但它们更紧凑。

答案 2 :(得分:0)

在支持第一类函数的语言中,可以像这样实现侦听器:

def myFunction() { //code }

button.onClick(myFunction) 

为简单起见,某些语言能够定义匿名函数(aka lambdas):

button.onClick({ // code}) 

被称为“匿名”因为不需要名称来引用它,所以使用到位。

Java没有第一类函数,而是使用实现某些接口的类实现监听器模式:

class myListener implements ButtonListener {
   public void listen(...);
}

button.onClick(myListener)

类似于匿名函数,为简单起见,java有匿名类的概念,你可以这样做:

button.onClick(new ButtonListener { 
   public void listen(..) { //code }
});

注意:这是一个简单的“ilustrative”示例,其中有一个发明的飞行api:P

在java 8中引入了第一类函数(闭包),这是java IMMO的一个巨大且非常好的补充。

内部类:有时候很好,一个类是在另一个类的范围内定义的,而不是最有用的java属性IMMO,我偶尔会使用它,但在其他语言中没有它。