在Java中,循环中局部变量初始化的最有效方法是什么?
局部变量的初始化是在循环中进行的,这可能会导致变量的值在下一次循环迭代时被意外地保留下来。为了解决这个问题,可以将变量的声明和初始化放在一个代码块中,这样可以限制变量的作用域,确保每次循环迭代时变量都会被重新初始化。
在上面的示例中,通过将变量foo和bar的声明放在一个代码块中,可以确保它们的作用域被限制在循环中。这样,每次循环迭代时,变量foo和bar都会被重新初始化,避免了值被意外地保留下来的问题。
在代码块中,可以通过调用item.getFoo()和item.getBar()方法来对变量foo和bar进行初始化。然后可以在代码块中的其他地方使用这些变量进行操作。
这种方法是一种有效的局部变量初始化的方式,可以确保变量在每次循环迭代时都被重新初始化,避免了值被意外地保留下来的问题。
在Java中,循环的本地变量初始化有什么最有效的方法?
问题的原因:
- 对于生成的字节码来说,两种方式是有差异的,但在性能上没有区别。
- 更重要的是,让代码尽可能简单、自包含和易于维护。因此,我更喜欢第一个例子。
- 简单的代码通常会被更好地优化,因为对JIT来说更容易尽可能多地进行优化。混乱的代码也会使JIT困惑,并阻止使用优化。
解决方法:
- 使用ASMifierClassVisitor来以可读的形式转储原始字节码(并可转换回原始字节码)。你会发现,javap忽略了一些不太重要的细节。
- 如果我比较左侧的代码和右侧的代码,左侧代码长951字节,右侧代码长935字节。
- 可以看到,至少调试行号是不同的,而且一些代码也不同,并且本地变量的定义顺序不同,并分配了不同的编号。
List- items = new ArrayList
- (); Foo foo; int bar; for (Item item : items) { foo = item.getFoo(); bar= item.getBar(); // do something with foo and bar }
List- items = new ArrayList
- (); for (Item item : items) { Foo foo = item.getFoo(); int bar = item.getBar(); // do something with foo and bar }
- 可以通过右键点击查看图片,以便更好地查看。
根据我贴出的链接,生成的字节码是相同的。
同意“首选第一个例子”。甚至可以将它们声明为final。
谢谢你的回答!当然,我理解不需要扩展范围的风险。问题只是关于性能(我应该在问题中强调这一点)。由于生成的字节码完全相同-性能上没有区别。
javap显示在重要细节上字节码是相同的。但至少行号不能相同。
我不确定你的意思-最终JVM将解释字节码(两种情况下字节码是相同的),而不是一些反向工程的字节码-或者我错过了什么?
字节码和反向工程字节码之间有什么区别?.class文件的大小不同,所以它们的内容也不同。
实际上,你不需要使用ASMifier,只需要使用javap -c -v来查看差异即可。