Java for-each on getter

Jon*_*röm 5 java getter foreach gwt

如果javac按照我的想法行事,以下几行将产生相同的性能:

for (Object o: getObjects()) {}
List<Object> os = getObjects(); for (Object o: os) {}
Run Code Online (Sandbox Code Playgroud)

是这样吗?或者它可能是特定于实现的?如果是这样:有人知道GWT吗?

SLa*_*aks 7

表现将是相同的.

Java编译器Iterator通过调用循环对象上的iterator()方法,将每个循环转换为围绕对象的循环.
因此,实际列表实例仅使用一次.(致电iterator())


Pas*_*ent 7

从Java语言规范:

14.14.2增强的陈述

增强的for语句具有以下形式:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement
Run Code Online (Sandbox Code Playgroud)

Expression必须具有类型 Iterable,否则它必须是数组类型(第10.1节),否则会发生编译时错误.

在增强for语句(第14.14节)的FormalParameter部分中声明的局部变量的范围是包含的Statement

增强for 陈述的含义通过翻译成基本for陈述给出.

如果类型Expression是子类型Iterable,那么让我们I成为表达式Expression的类型 .iterator().增强for语句等同于for表单的基本语句:

for (I #i = Expression.iterator(); #i.hasNext(); ) {

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}
Run Code Online (Sandbox Code Playgroud)

#i编译器生成的标识符在何处是与增强的for语句发生时的范围(第6.3节)中的任何其他标识符(编译器生成的或其他标识符)不同.

如您所见,Expression仅在for循环表达式的第一部分中提及,因此仅评估一次.所以你的两条线会产生相同的性能.


Jas*_*all 5

从纯Java角度来看,这些答案似乎都是正确的.此外,如果可以,GWT编译器实际上将进一步重写增强的for循环,在生成JavaScript之前进入常规for循环.所以它实际上最终会看起来像:

for (int i = 0; i < getObjects().size(); i++) {
  Object o = getObjects().get(i);
  // ...
}
Run Code Online (Sandbox Code Playgroud)

原因?如果从未引用List iterator对象,则可以将其声明为死代码,并且不会在JavaScript中重写,从而导致较小的下载大小.这种优化应该对代码的实际执行没有任何影响.

有关GWT编译器为减小JS大小所做的其他疯狂事情的​​更多详细信息,请参阅今年的Google I/O中使用GWT编译器优化应用程序.