这是一个问题,值得研究javap。
public class Foo
{
public int bar(){
System.out.println("foo");
return 8;
}
public int foo(){
int x;
System.out.println("foo");
return 8;
}
}
请注意,foo()和bar()之间的区别是,一个声明一个局部变量x,另一个声明不是。
现在看看jvm代码(使用javap -v Foo在你的机器上看到这个)
public int bar();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String foo
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: bipush 8
10: ireturn
LineNumberTable:
line 6: 0
line 7: 8
public int foo();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String foo
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: bipush 8
10: ireturn
LineNumberTable:
line 12: 0
line 13: 8
}
有趣的是,逐行输出是相同的,但是bar的局部变量是1,而foo是2.因此,看起来空间确实是为x分配的,即使编译器输出不使用它。
更新:做一些更多的研究,我发现this page这向我建议,虽然编译的字节码意味着空间分配给x,它可能确实被jvm优化。不幸的是,我没有找到对所执行的优化的完整描述。特别地,compiling的JVM文档章节没有提到从堆栈中删除未使用的变量。所以,除了进一步的发现,我的答案将是它的实现依赖,但它似乎像任何自尊的编译器将执行的优化。注意,这是一个局部变量而不是一个字段,这并不重要 – 事实上,局部变量是最有可能被优化掉的,因为它们是最容易分析和消除的。 (正是因为它们是本地的)