在Java中匿名类有什么用?我们可以说使用匿名类是Java的优点之一吗?
当前回答
匿名内部类实际上是闭包,所以它们可以用来模拟lambda表达式或“委托”。以这个接口为例:
public interface F<A, B> {
B f(A a);
}
您可以匿名使用它在Java中创建一级函数。假设你有以下方法,返回给定列表中第一个比i大的数字,如果没有比i大的数字,则返回i:
public static int larger(final List<Integer> ns, final int i) {
for (Integer n : ns)
if (n > i)
return n;
return i;
}
然后你有另一个方法返回给定列表中第一个比i小的数字,如果没有比i小的数字,则返回i:
public static int smaller(final List<Integer> ns, final int i) {
for (Integer n : ns)
if (n < i)
return n;
return i;
}
这些方法几乎是相同的。使用一类函数类型F,我们可以将它们重写为一个方法,如下所示:
public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) {
for (T t : ts)
if (f.f(t))
return t;
return z;
}
你可以使用匿名类来使用firstMatch方法:
F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> {
Boolean f(final Integer n) {
return n > 10;
}
};
int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x);
这是一个非常做作的例子,但是很容易看出,能够像传递值一样传递函数是一个非常有用的特性。请看Joel自己写的“你的编程语言能做到这一点吗?”
用这种风格编写Java的一个很好的库:函数式Java。
其他回答
它们通常用作详细形式的回调。
我想你可以说,与没有它们和每次都必须创建命名类相比,它们是一个优势,但类似的概念在其他语言中实现得更好(如闭包或块)。
下面是一个swing的例子
myButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
// do stuff here...
}
});
尽管它仍然很冗长,但它比强迫您为每个throw away侦听器定义一个命名类要好得多(尽管这取决于情况和重用,这可能仍然是更好的方法)
您可以这样使用匿名类
TreeSet treeSetObj = new TreeSet(new Comparator()
{
public int compare(String i1,String i2)
{
return i2.compareTo(i1);
}
});
我使用匿名对象来调用新线程。
new Thread(new Runnable() {
public void run() {
// you code
}
}).start();
所谓的“匿名类”,我想你是指匿名的内部类。
匿名内部类在创建具有某些“额外”(如重写方法)的对象实例时非常有用,而不必实际继承一个类。
我倾向于使用它作为附加事件监听器的快捷方式:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// do something
}
});
使用这个方法可以使编码更快一点,因为我不需要创建一个额外的实现ActionListener的类——我可以实例化一个匿名的内部类,而不需要实际创建一个单独的类。
我只在“快速而肮脏”的任务中使用这种技巧,让整个类感觉没有必要。拥有多个做完全相同事情的匿名内部类应该被重构为一个实际的类,无论是内部类还是单独的类。
是的,匿名内部类绝对是Java的优势之一。
使用匿名内部类,您可以访问周围类的final变量和成员变量,这在侦听器等方面很方便。
但是一个主要的优点是,内部类代码(至少应该)与周围的类/方法/块紧密耦合,具有特定的上下文(周围的类、方法和块)。
推荐文章
- JavaFX应用程序图标
- Java:强/软/弱/幻影引用的区别
- 在序列化和反序列化期间JSON属性的不同名称
- 获取Android设备名称
- Gradle代理配置
- 如何获得具有已知资源名称的资源id ?
- 在Android上将字符串转换为整数
- 为什么“System.out。”println“工作在Android?
- 在Java中什么时候使用可变参数?
- Mockito的argumentCaptor的例子
- 我如何告诉Spring Boot哪个主类用于可执行jar?
- 如何将Java8流的元素添加到现有的列表中
- 在Java 8中是否可以转换流?
- 不区分大小写的字符串作为HashMap键
- 什么是maven中的“pom”打包?