这是一个值得用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的空间似乎确实已分配。它。
更新:对此进行了更多研究,我发现此页面向我暗示,尽管编译后的字节码暗示为x分配了空间,但jvm确实可以对其进行优化。不幸的是,我找不到所执行优化的完整描述。特别是有关编译的JVM文档章节没有提到从堆栈中删除未使用的变量。因此,除非有进一步的发现,我的答案是它与实现有关,但似乎是任何自重的编译器都会执行的优化。还要注意,这是一个局部变量而不是字段也没关系-
实际上,局部变量是最有可能被优化的变量,因为它们最容易分析和消除。(正是因为它们是本地的)



