0

可能重复:
在循环内部或外部声明变量

请考虑以下 2 个 Java 代码示例:

// 1st sample
for (Item item : items) {
    Foo foo = item.getFoo();
    int bar = item.getBar();
    // do smth with foo and bar
}

// 2nd sample
Foo foo;
int bar;
for (Item item : items) {
    foo = item.getFoo();
    bar = item.getBar();
    // do smth with foo and bar
}

样本之间的性能/内存消耗有什么不同吗?如果是,那么它是否取决于句柄的类型(对象与原语)?

4

2 回答 2

8

它在生成的字节码方面有所不同,但在性能方面没有区别。

更重要的是使代码尽可能简单、自包含和可维护。出于这个原因,我更喜欢第一个例子。

顺便说一句:更简单的代码通常会得到更好的优化,因为 JIT 更容易进行尽可能多的优化。混淆代码也会混淆 JIT,它会阻止优化被使用。

如果您使用ASMifierClassVisitor以可读形式转储原始字节码(并且可以转换回原始字节码),您会看到它javap掩盖了一些不那么重要的细节。

如果我比较(在左下方) 951 字节长。

List<Item> items = new ArrayList<Item>();

Foo foo;
int bar;
for (Item item : items) {
    foo = item.getFoo();
    bar= item.getBar();
    // do something with foo and bar
}

带有(在右下方)和 935 字节长。

List<Item> items = new ArrayList<Item>();

for (Item item : items) {
    Foo foo = item.getFoo();
    int bar = item.getBar();
    // do something with foo and bar
}

您至少可以看到调试行号必须不同,而且某些代码也不同,以及以不同顺序定义的局部变量并给出不同的分配号。

在此处输入图像描述

您可以right click=>View Image更好地查看图像。

于 2012-09-27T07:55:55.237 回答
1

如果您担心第二个示例中的范围泄漏,您还可以通过将其放入块中来限制范围:

{
    Foo foo;
    int bar;
    for (Item item : items) {
        foo = item.getFoo();
        bar = item.getBar();
        // do smth with foo and bar
    }
}
于 2012-09-27T07:58:36.753 回答