在java中,通常有一些对象只用于包装函数,而且没有自己的任何状态。例如:
class Foo {
void foo () {
System.out.println("foo");
}
static public void main(String[] arg) {
Foo foo = new Foo();
foo.foo();
}
}
我想知道表达式new Foo()
是否针对C ++中的函数指针赋值进行了优化。这似乎是一个显而易见的事情,但是当我考虑它时,编译器必须检查foo
是否未用于同步(可能还有其他什么?)。标准是否对此有所说明?
答案 0 :(得分:1)
标准(VM规范和JLS)对此没有任何说明,完全由VM实现来处理优化。
所有标准指定的是一组需要遵守的不变量。如果VM保证你所做的将看起来像创建一个对象,然后调用一个方法,然后处理它,它可以做它想做的事。
虽然优化的确切方式可能会有所不同,但这种低级别的事情是瓶颈的极为罕见。但是,由于优化是在运行时完成的,因此您可以合理地确定只有在您的代码被大量调用时才会执行它们;不经常使用的代码被解释而不是编译成机器代码。 (但即使这可能会从VM更改为VM,并且可能取决于特定的命令行选项。)在您的情况下,可能会发生的事情是,经过大量运行后,VM完全内联该方法,摆脱对象创建和方法调用。
您可以“优化”代码的一件事就是声明Foo
(和foo()
)final。
答案 1 :(得分:0)
据说,对象的创建只需要约10条指令。所以这是一个非常便宜的操作。
来自here
Sun估计大约十台机器指令的分配成本。
因此创建新对象几乎没有开销。如果你把所有东西都制成静态并且只把它放在一个类中,那么很快就会混乱。
答案 2 :(得分:0)
如果您没有任何州,那么您可以制作这些方法static
。我不认为java编译器会像你想的那样对它进行优化,因为这会改变语义。如果通过new
创建对象,则将其转换为其他内容会改变语义。
我认为根本不会使用函数指针赋值的概念。
答案 3 :(得分:0)
想象一下当你有大量静态辅助方法的场景。如果您在要使用它们的类中实现它们,那么您的课程将变得越来越大。
但是如果你在单独的单例或静态类中编写它们,那么你只需要保存一个引用,并通过它调用方法,这样你就可以在处理多个实例时节省内存。
我可能错了,但这是我想到的第一件事。
答案 4 :(得分:0)
new Foo()将创建一个新对象
在Java中,有对象,数组和基元,没有别的
答案 5 :(得分:0)
不确定标准是什么意思。但我不认为像你提到的任何优化都已完成。为什么我认为我确定?因为它会破坏java.lang.Class的功能。来自API doc:
类Class的实例表示正在运行的Java应用程序中的类和接口。