27

这两种做事方式在效率(例如执行时间、代码大小等)上是否存在差异?

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

使用匿名对象:

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() {}
};
4

6 回答 6

43

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

这不会体现在性能上,但如果您对这些类进行序列化,则会对您产生影响。

于 2010-06-12T10:40:19.013 回答
20

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

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

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

于 2010-06-12T10:37:44.887 回答
18

It's important to realize that anonymous classes are still classes that were known and fully-compiled at compile time. The fact that, say, you're defining an anonymous class body, perhaps with many methods and fields etc within a loop, doesn't mean that the runtime has to compile that type on every iteration.

Thus, any difference in performance between the two approaches are negligible. The important factors to consider are things like readability, reusability, testability, etc.

于 2010-06-12T10:47:56.187 回答
5

I actually HAVE noticed a significance performance hit when instantiating many instances of an anonymous class.

Thinking if might be due to the local class being static I removed that and it made no difference.

In my case, I was doing something 1000 choose 3 times which is 499,500. The version with the local class (regardless of static or not) took 26 seconds and the version with the anonymous functionally identical class took 2 minutes 20 seconds.

于 2013-05-15T17:21:00.653 回答
5

Regarding performance you should consider if an inner class should be created or not at all.

An example for bad practice is something like:

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

While this syntactical convenience looks smart at a first glance, this (often unnoticed) creates an anonymous inner class whose object keeps a reference to the outer instance. As this object is also given to the outside as result value of someMethod, you cannot be sure what your caller does with this list. If he puts the resulting ArrayList instance into some static variable, your current Object will be kept forever too!

于 2014-10-29T09:35:43.207 回答
0

Speculating about code performance is an excellent way of wasting your time. Nothing compares to actually benchmarking the code. If you're worried about performance, measure the code. If you suspect that your code is sub-optimal, profile the code to figure out where the time is spent, then try to improve those parts. At this time it may be appropriate to actually study the byte code to see if that may give you a hint which implementation is more efficient.

When you've done that, measure the code again to make sure that you didn't make things worse, for example by making the code uglier and more difficult to maintain.

于 2010-06-12T10:49:53.693 回答