在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侦听器定义一个命名类要好得多(尽管这取决于情况和重用,这可能仍然是更好的方法)
匿名内部类用于以下场景:
1)。对于重写(子类化),当类定义除当前情况外不可用时:
class A{
public void methodA() {
System.out.println("methodA");
}
}
class B{
A a = new A() {
public void methodA() {
System.out.println("anonymous methodA");
}
};
}
2)。为了实现一个接口,当接口的实现仅在当前情况下是必需的:
interface InterfaceA{
public void methodA();
}
class B{
InterfaceA a = new InterfaceA() {
public void methodA() {
System.out.println("anonymous methodA implementer");
}
};
}
3.) 参数定义匿名内部类:
interface Foo {
void methodFoo();
}
class B{
void do(Foo f) { }
}
class A{
void methodA() {
B b = new B();
b.do(new Foo() {
public void methodFoo() {
System.out.println("methodFoo");
}
});
}
}
优化代码的最佳方法。也可以用于类或接口的重写方法。
import java.util.Scanner;
abstract class AnonymousInner {
abstract void sum();
}
class AnonymousInnerMain {
public static void main(String []k){
Scanner sn = new Scanner(System.in);
System.out.println("Enter two vlaues");
int a= Integer.parseInt(sn.nextLine());
int b= Integer.parseInt(sn.nextLine());
AnonymousInner ac = new AnonymousInner(){
void sum(){
int c= a+b;
System.out.println("Sum of two number is: "+c);
}
};
ac.sum();
}
}
还有一个好处: 正如你所知道的,Java不支持多重继承,所以如果你使用“线程”类作为匿名类,那么类仍然有一个空间留给任何其他类来扩展。
匿名内部类用于创建一个永远不会被再次引用的对象。它没有名称,在同一个语句中声明和创建。 这用于通常使用对象变量的地方。用new关键字替换变量,调用构造函数和{and}内的类定义。
当用Java编写线程程序时,它通常是这样的
ThreadClass task = new ThreadClass();
Thread runner = new Thread(task);
runner.start();
这里使用的ThreadClass是用户定义的。该类将实现创建线程所需的Runnable接口。在ThreadClass中run()方法(Runnable中唯一的方法)也需要实现。 显然,去掉ThreadClass会更有效,这正是匿名内部类存在的原因。
请看下面的代码
Thread runner = new Thread(new Runnable() {
public void run() {
//Thread does it's work here
}
});
runner.start();
这段代码替换了最上面的示例中对任务的引用。Thread()构造函数中的匿名内部类并没有单独的类,而是返回一个未命名的对象,该对象实现了Runnable接口并重写了run()方法。方法run()将包含执行线程所需工作的语句。
在回答“匿名内部类是否是Java的优点之一”这个问题时,我不得不说我不太确定,因为目前我对许多编程语言都不熟悉。但我能说的是,这绝对是一种更快更简单的编码方法。
参考资料:山姆自学Java在21天第七版
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap