在Java中,循环中局部变量初始化的最有效方法是什么?

10 浏览
0 Comments

在Java中,循环中局部变量初始化的最有效方法是什么?

这两个Java代码示例有什么性能/内存消耗上的差异吗?如果有的话,是否取决于句柄的类型(对象还是原始类型)?

0
0 Comments

局部变量的初始化是在循环中进行的,这可能会导致变量的值在下一次循环迭代时被意外地保留下来。为了解决这个问题,可以将变量的声明和初始化放在一个代码块中,这样可以限制变量的作用域,确保每次循环迭代时变量都会被重新初始化。

在上面的示例中,通过将变量foo和bar的声明放在一个代码块中,可以确保它们的作用域被限制在循环中。这样,每次循环迭代时,变量foo和bar都会被重新初始化,避免了值被意外地保留下来的问题。

在代码块中,可以通过调用item.getFoo()和item.getBar()方法来对变量foo和bar进行初始化。然后可以在代码块中的其他地方使用这些变量进行操作。

这种方法是一种有效的局部变量初始化的方式,可以确保变量在每次循环迭代时都被重新初始化,避免了值被意外地保留下来的问题。

0
0 Comments

在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来查看差异即可。

0