在Java中匿名类有什么用?我们可以说使用匿名类是Java的优点之一吗?
当前回答
您可以这样使用匿名类
TreeSet treeSetObj = new TreeSet(new Comparator()
{
public int compare(String i1,String i2)
{
return i2.compareTo(i1);
}
});
其他回答
匿名内部类用于创建一个永远不会被再次引用的对象。它没有名称,在同一个语句中声明和创建。 这用于通常使用对象变量的地方。用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世界中,应该避免使用finalize方法,除非你真的需要它们。你必须记住,当你重写子类的finalize方法时,你也应该总是调用super.finalize(),因为超类的finalize方法不会自动调用,你可能会遇到内存泄漏的问题。
所以考虑到上面提到的事实,你可以像这样使用匿名类:
public class HeavyClass{
private final Object finalizerGuardian = new Object() {
@Override
protected void finalize() throws Throwable{
//Finalize outer HeavyClass object
}
};
}
使用这种技术,您可以让自己和其他开发人员在需要finalize方法的重量级类的每个子类上调用super.finalize()。
匿名内部类在为不同的对象提供不同的实现时是有益的。但是应该非常谨慎地使用,因为它会给程序的可读性带来问题。
您可以在需要在另一个函数中为特定目的创建类的情况下使用它,例如,作为侦听器,作为可运行对象(生成线程)等。
其思想是,从函数代码内部调用它们,因此永远不会在其他地方引用它们,因此不需要命名它们。编译器只是枚举它们。
它们本质上是语法糖,当它们变大时通常应该转移到其他地方。
我不确定这是否是Java的优点之一,但如果您确实使用它们(不幸的是,我们都经常使用它们),那么您可能会认为它们是优点之一。
似乎这里没有人提到,但你也可以使用匿名类来保存泛型类型参数(通常由于类型擦除而丢失):
public abstract class TypeHolder<T> {
private final Type type;
public TypeReference() {
// you may do do additional sanity checks here
final Type superClass = getClass().getGenericSuperclass();
this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
public final Type getType() {
return this.type;
}
}
如果你用匿名的方式实例化这个类
TypeHolder<List<String>, Map<Ineger, Long>> holder =
new TypeHolder<List<String>, Map<Ineger, Long>>() {};
然后,这样的holder实例将包含传递类型的非擦除定义。
使用
这对于构建验证器/反序列化器非常方便。此外,您还可以使用反射实例化泛型类型(因此,如果您想在参数化类型中执行新的T()—欢迎您!)
不便/限制
您应该显式地传递泛型参数。如果不这样做,将导致类型参数丢失 每次实例化都会花费编译器生成额外的类,这会导致类路径污染/jar膨胀
推荐文章
- 在流中使用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