匿名内部类有哪些优势(相较于非匿名内部类)?

7
考虑以下内容(匿名):
speakBtn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
    }});

与此相比:(非匿名):

class MyOuterClass {
    private class MyOnClickListener implements OnClickListener {
        @Override
        public void onClick(View view) {
            mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
        }
    }

    // later (inside some method)...
        speakBtn.setOnClickListener(new MyOnClickListener());
}

除了代码行数更少之外,匿名形式还有其他优点吗?

是否存在性能优势?


匿名内部类语法不够简洁吗? - Tom Hawtin - tackline
6个回答

4
匿名内部类比内部类(如问题示例代码中的内部类)具有优势,因为它关闭了方法的局部变量(尽管只有最终变量可用)。
通常,内部类可以很容易地转换为具有匿名内部类的方法,这有助于减少冗余。如果您的内部类非常大,以至于您想使其成为非本地类,那么您可能需要考虑与IDE一起将其放入新文件作为外部类。
(也有本地类,这是普通命名的内部类,在方法内定义并关闭局部变量。)

你能解释一下“closes over”是什么意思吗?谢谢。 - an00b
@an00b 不是很清楚。这是一个链接:http://en.wikipedia.org/wiki/Closure_(computer_programming) - Tom Hawtin - tackline
哇!非常感谢。您刚刚使您的答案成为被接受的答案(尽管许多其他答案也非常好)。我现在将学习什么是一级函数,然后我将学习什么是闭包。 - an00b

2
非匿名类的优点在于可以重复使用该类。我认为使用匿名内部类的唯一原因是简洁。

2
相反地,有时您希望源代码清楚地表明某个代码块不适用于一般用途,而仅适用于声明站点。匿名类可以实现此功能。 - Vance Maverick
1
你也可以使用private内部类来实现这个。 - Tony Casale

2

我喜欢命名内部类的原因:

  • 它们有一个名称。当我在堆栈跟踪中看到 MyOuterClass$MyOnClickListener 而不是匿名内部类的 MyOuterClass$1 时,我发现调试更容易。
  • 有时将内部类的实际代码与使用它的位置分开可以提高可读性。如果我已经在一个长方法中或缩进超过两个级别,我尤其喜欢这样做。

关于性能问题,匿名内部类会被编译成普通类,因此不应该有性能差异。


1

优点在于作为开发人员,您无需键入额外的按键即可节省时间。 :)

哦,它还可以防止您不必要地为每个东西想出一个新名称(这可能会在某些情况下导致名称冲突)。


谢谢。我在问题中已经说过“除了行数较少”,这包括“不需要输入额外的按键”。 :) 命名空间考虑肯定是一个额外的优势。 - an00b
@an00b:是的,我意识到了,但这是如此重要的优势,而其他优势实在太少,所以值得一提。 :) - user541686

1

有一个明显的缺点:

如果你需要多个相同的内部类,你几乎需要使用明确定义的类。根据你描述的情况,不需要这样做。但是你可能在以后的某个时间决定需要另一个执行相同功能但是是不同对象的对象。


0

匿名类的目的是使所需的类变成本地类。当我们非常确定某个类A是类B的唯一使用者,而且其他地方都不会用到类B时,最好将类B定义为类A内部的匿名类。我们在同一个类中编写所需的逻辑,因此避免了从外部创建对象。这将在代码可维护性方面更容易维护。因此,匿名类使您的代码更加简洁。它们使您能够同时声明和实例化一个类。它们类似于本地类,但没有名称。如果您只需要使用本地类一次,请使用它们。


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