Java匿名类效率的含义

这两种做事方式之间的效率(例如执行时间,代码大小等)是否有任何差异?

下面是创建对象并且什么都不做的人为例子,但我的实际场景可能是创建新的线程,监听器等。假设以下代码片段在循环中发生,以便它可能有所作为。

使用匿名对象:

void doSomething() { for (/* Assume some loop */) { final Object obj1, obj2; // some free variables IWorker anonymousWorker = new IWorker() { doWork() { // do things that refer to obj1 and obj2 } }; } } 

首先定义一个类:

 void doSomething() { for (/* Assume some loop */) { Object obj1, obj2; IWorker worker = new Worker(obj1, obj2); } } static class Worker implements IWorker { private Object obj1, obj2; public CustomObject(Object obj1, Object obj2) {/* blah blah */} @Override public void doWork() {} }; 

匿名类和顶级类之间唯一的实际区别是匿名类将包含对外部类的隐式引用。

这不会在性能方面表现出来,但如果您将这些类序列化,则会对您产生影响。

如果有任何性能差异应该很少。 如果存在差异,它将处于不值得担心的水平。

IMO,您应该专注于编写可读和可维护的代码,并忽略“微观”性能问题,直到您有明确的证据表明它们是重要的……基于对应用程序进行概要分析。

(对于记录,当匿名内部类引用封闭范围中的final时,这是通过隐藏的构造函数参数和隐藏的实例属性在字节码级别实现的。字节码将与您获得的字节码几乎相同来自你的其他实现。)

重要的是要意识到匿名类仍然是在编译时已知并完全编译的类。 事实上,比如说,你定义了一个匿名类主体,可能在循环中有许多方法和字段等,这并不意味着运行时必须在每次迭代时编译该类型。

因此,两种方法之间的任何性能差异都可以忽略不计。 要考虑的重要因素是可读性,可重用性,可测试性等。

关于性能,您应该考虑是否应该创建内部类。

不良做法的一个例子是:

 public List someMethod() { return new ArrayList() {{ add("Item one"); add("Item two"); }}; } 

虽然这种语法上的便利性在第一眼看上去很聪明,但这(通常不被注意)会创建一个匿名内部类,其对象保持对外部实例的引用。 由于此对象也作为someMethod的结果值提供给外部,因此您无法确定调用者对此列表的作用。 如果他将生成的ArrayList实例放入某个静态变量中,那么您当前的Object也将永远保存!

实际上,在实例化匿名类的许多实例时,我注意到了重要性。

考虑是否可能是由于本地类是静态的,我删除了它并没有区别。

在我的情况下,我做了1000次选择3次,即499,500次。 具有本地类的版本(无论是否为静态)花费26秒,具有匿名function相同类的版本花费2分20秒。

推测代码性能是浪费时间的绝佳方式。 没有比实际基准测试代码更好的了。 如果您担心性能,请测量代码 。 如果您怀疑代码是次优的,请分析代码以确定花费的时间,然后尝试改进这些部分。 此时,实际研究字节代码可能是合适的,看看是否可以提示哪个实现更有效。

当你完成后, 再次测量代码,以确保你没有让事情变得更糟,例如通过使代码更丑陋和更难维护。