关于内存使用和变量实例化哪个更好或没有区别:
此
for(int i = 0; i < someValue; i++)
{
Obj foo = new Obj();
Use foo.....
}
相反:
Obj foo;
for(int i = 0; i < someValue; i++)
{
foo = new Obj();
Use foo.....
}
答案 0 :(得分:11)
没有区别。内存使用方面的任何潜在差异都将由编译器优化。
如果您编译(使用javap -c
)这两个示例并比较字节码,您会发现字节码是相同的。当然,这取决于JVM版本。但是,由于这个例子是如此微不足道,因此可以安全地假设它们的内存效率都不高于另一个。
代码:
public class example1 {
public static void main(String[] args) {
for (int i=0; i<10; i++) {
Object a = new Object();
}
}
}
字节码:
public class example1 extends java.lang.Object{
public example1();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 22
8: new #2; //class java/lang/Object
11: dup
12: invokespecial #1; //Method java/lang/Object."<init>":()V
15: astore_2
16: iinc 1, 1
19: goto 2
22: return
}
代码:
public class example2 {
public static void main(String[] args) {
Object a;
for (int i=0; i<10; i++) {
a = new Object();
}
}
}
字节码:
public class example2 extends java.lang.Object{
public example2();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_2
2: iload_2
3: bipush 10
5: if_icmpge 22
8: new #2; //class java/lang/Object
11: dup
12: invokespecial #1; //Method java/lang/Object."<init>":()V
15: astore_1
16: iinc 2, 1
19: goto 2
22: return
}
答案 1 :(得分:6)
现代JVM的工作方式都相同,编译器优化也会使两者相同。
忽略编译器优化和现代JVM,第一种方法更好。
答案 2 :(得分:5)
第一个例子在对象范围方面最有意义,但两者都应该像另一个一样具有内存效率。
答案 3 :(得分:5)
您的示例之间没有区别,正如其他答案所指出的那样。但是,问题是:如果你的例子很慢,你应该怎么做?
如果要在真正的性能关键部分减少分配/垃圾收集所花费的时间,请考虑重复使用对象,而不是在每次迭代时分配新对象。
foo = new Obj();
for(int i = 0; i < someValue; i++)
{
foo.init(i);
Use foo.....
}
来自java performance tuning(一本旧书,但在现代的jvm:s和.NET clr中也是如此)
......对象的创建成本很高。哪里 重复使用同一个对象是合理的,你应该这样做。你需要 要注意什么时候不要打电话给新人。一个相当明显的情况是 当你已经使用了一个物体并且可以在它之前丢弃它 即将创建同一个类的另一个对象。你应该看看 对象并考虑是否可以重置字段和 然后重用该对象,而不是扔掉它并创建另一个。 这对于经常出现的对象尤为重要 使用和丢弃
答案 4 :(得分:3)
编译器优化将使两者相同。但是,如果您忽略编译器优化,我更喜欢第一种方法。更重要的是,即使Joshua Bloch也建议在Effective Java中这样做(很好的阅读)。
答案 5 :(得分:1)
编译器应该为您优化这一点。我更喜欢第一个,因为它更具可读性。让Object foo
具有更大的范围可能会引起混淆。