gpt4 book ai didi

java - 如果大量使用匿名内部类会对性能产生多大影响?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:11:05 27 4
gpt4 key购买 nike

===结论====

https://softwareengineering.stackexchange.com/a/149569 找到了一本好书哪个州

当前的 GC 算法实际上针对创建许多短生命周期的小对象进行了优化,所以我认为在项目中大量使用匿名内部类对性能来说并不是什么大问题*

============================================= =========================

因为函数在当前Java(Java7)中不是一等公民,使用匿名内部类似乎是实现完全异步应用程序的唯一途径。

我知道它会在一定程度上带来更大的内存占用和垃圾收集器的负担,但我不知道它会严重到什么程度?最近我的同事和我吵架,因为我的代码是利用匿名内部类以函数式风格编写的,他的反对完全是关于性能的。虽然我不同意,但我无法举出任何例子来证明我自己。我知道 groovy 正在使用匿名类实现闭包,但是 groovy 确实比 java 性能差(当然匿名应该只承担一部分责任,因为 groovy 也大量使用反射)。

所以我想知道在现实世界中,是否有任何项目仅仅因为性能而放弃匿名类?像 swing 这样的 UI 框架怎么样?是否大量使用匿名类?

没有anonymous,我无法想象在java中如何优雅的实现async。我们的项目已经使用了一种非常丑陋的方法来使类方法充当函数指针。我讨厌那么多,想说服人们匿名上课是正确的方式。

我的例子:

// basically, I use Completion interface to make normal java methods work in async manner

public interface Completion {
void success();

void fail(String reason);
}


void methodA(Completion completion) {

do_some_business_by_calling_remote_service ....

when remote_service_ack_success:
completion.success();
else:
completion.fail(remote_service_error);

}

void methodB() {
methodA(new Completion() {
public void success() {
continue to do something;
}

public void fail(String err) {
handle error
}
});
}

最佳答案

这里基本上有两个问题,它们都与匿名方面无关。除了没有名称外,匿名类与常规内部类并没有什么不同。匿名内部类被编译为常规内部类,而后者与静态嵌套类仍然没有任何区别。

问题 1 是因为它们是内部的,所以它们保留对封闭类的引用:

class Outer {
interface Inner {}

Inner inner = new Inner() {
{
System.out.println(Outer.this);
}
};
}

这不是什么大问题,大多数情况下这是需要的,因为您正在做一些功能性的事情并且想在内部类中使用外部实例的成员。但这可能会产生问题,因为只要内部类还活着,就不能对外部类进行垃圾回收。

问题 2 确实它们是一个对象,因此您的 methodB 每次调用时都会创建一个新对象。

显而易见的解决方案是只创建一次:

class MyProcess {

final Completion myCompletion = new Completion() {
@Override
public void success() {}
@Override
public void fail(String err) {}
}

void methodA(Completion c) {}

void methodB() {
methodA(myCompletion);
}
}

虽然您喜欢的似乎是语法,但并没有真正的解决方案来保持语法而不同时创建对象。

我个人的看法:如果您不经常调用此方法,我同意语法可以很好且清晰。如果您经常调用它,请切换到单个对象,因为您正在占用内存空间。如果它被调用 1000 次,那就是 1000 个对象。对象大小因平台而异,但通常至少为 8 或 16 字节 + 指向外部实例的指针。这不是一个巨大的影响,但它可能会促使垃圾收集运行,这可能会导致微妙的停顿。

对了,我又在思考这个问题,想到了下面的想法:

Completion myLazyCompletion;

void methodB() {
methodA(myLazyCompletion != null ? myLazyCompletion :
(myLazyCompletion = new Completion() {

// overrides

})
);
}

我会说不要那样做,但我认为这很有趣。 :)

关于java - 如果大量使用匿名内部类会对性能产生多大影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21009712/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com