当前位置: 首页 > 面试题库 >

为什么在Java的for-each循环中需要声明变量

邓嘉致
2023-03-14
问题内容

每个循环的通常形式是:

for(Foo bar: bars){
    bar.doThings();
}

但是,如果我想在循环之后一直保留bar,则 不能 为每个循环使用:

Foo bar = null;
// - Syntax error on token "bar", Identifier expected after this token
for(bar: bars){ 
    if(bar.condition())
        break;
}
bar.doThings();

for循环获取上述语法错误。

为什么是这样? 我对变通办法不感兴趣,但只是对这种限制背后的考虑感到好奇。

相反,使用普通的for循环,变量可以在外部声明或根本不声明。

int i = 1;
for(;i<max;i++){
    for(;;){
        // Do things
    }
}

问题答案:

这是一个很好的问题,我很乐意看到一些深入的答案。但是,官方文档说:

这些缺点为设计师所知,他们明智地决定采用一种干净,简单的结构来覆盖绝大多数情况。

绝大多数情况是我的答案。

从侧面来看,就我个人而言,我认为foreachJava循环对于标准迭代器循环而言只是一种不错的语法。因此,编译器为结构创建迭代器,并使用变量获取当前迭代的值。为了确保变量已被初始化,您需要在循环范围内声明它(我认为这可以防止变量在其他地方使用,例如在另一个线程中使用)。因此,您不能在循环后使用变量。但是,这只是我的看法,如果能更好地了解它,我将非常高兴。:)

编辑 这里是有关Java循环的有趣文章foreach

*我分析了 *另一个编辑 (使用jclasslib的这些方法的字节码:

 private static void testForEach(ArrayList<String> als) {
  for(String s: als)
    System.out.println(s);
 }

 private static void testIterator(ArrayList<String> als) {
  for(Iterator<String> is = als.iterator(); is.hasNext();) {
   String s = is.next();
   System.out.println(s);
  } 
 }

两种方法都由相同的字节码表示:

 0 aload_0
 1 invokevirtual #2 <java/util/ArrayList.iterator>
 4 astore_1
 5 aload_1
 6 invokeinterface #3 <java/util/Iterator.hasNext> count 1
11 ifeq 34 (+23)
14 aload_1
15 invokeinterface #4 <java/util/Iterator.next> count 1
20 checkcast #5 <java/lang/String>
23 astore_2
24 getstatic #6 <java/lang/System.out>
27 aload_2
28 invokevirtual #7 <java/io/PrintStream.println>
31 goto 5 (-26)
34 return

区别在于第1行,后一种方法使用`invokevirtual

为什么如此 。在讨论的背景下,我虽然很有趣,但也许值得一读。



 类似资料:
  • 问题内容: 在循环内部声明变量是否不好?在我看来,这样做,如下面的第一个代码块所示,将使用第二次的十倍的内存…由于在循环的每次迭代中都创建了一个新的字符串。这样对吗? 与 问题答案: 在循环内部声明变量是否不好? 一点也不!它将变量本地化到其使用点。 在我看来,如下面的第一个代码块所示,这样做将使用十倍于第二个内存的内存。 编译器可以优化内容以保持内存使用效率。仅供参考:如果您使用关键字告诉您变量

  • 问题内容: Java7的try-with-resources非常好,但是我无法绕开为什么需要在语句中包括资源声明的问题。我的直觉说以下应该是可能的: las,这会导致语法错误(含糊地期待a )。将类型定义/声明移动到语句中是可行的,这当然会将事物移动到相应的范围内。当我想从封闭中获得更多收益时,我可以弄清楚该如何解决,我对 为什么 编译器需要这样的东西很感兴趣。 问题答案: 您的版本未明确定义应关

  • 问题内容: ja块变量还是局部变量?我看到j的作用域只是直到for循环结束 问题答案: 局部变量在方法,构造函数或块中声明。 由此可见, 所有块变量都是局部变量。 按照块的定义 块是平衡括号之间的一组零个或多个语句,可以在允许单个语句的任何地方使用。 所以 无论在块内声明什么变量,范围都限于该块。 因此范围仅限于该块内部。那是循环。

  • 问题内容: 在包含forEach循环的行上引发了出站异常,但是据我所知,此代码没有错。for循环从char数组的元素0开始,一直循环直到到达最后一个元素…但是当我尝试使用更长的for循环来执行此代码时,即 该代码按预期工作。 为什么在这种情况下for循环起作用,而forEach循环不起作用? 问题答案: 如果您需要在循环中使用索引访问某些内容,请使用for,而不是foreach(已增强)。 现在,

  • For Each循环用于为数组或集合中的每个元素执行语句或一组语句。 For Each循环类似于For循环; 但是,为数组或组中的每个元素执行循环。 因此,步进计数器将不存在于这种类型的循环中。 它主要用于数组或在File系统对象的上下文中使用,以便递归操作。 语法 (Syntax) 以下是VBA中For Each循环的语法。 For Each element In Group [state

  • 问题内容: 在Java中,我们不能与另一个具有相同名称的变量在同一作用域中声明一个变量: 语法错误,无法编译。但是,如果我们将其放入循环中: 不产生错误,效果很好。我们基本上是在声明相同的变量。是什么原因?在此背后我不知道/不了解的逻辑是什么? 问题答案: 考虑一下这种方式,在每个循环之后,作用域被“破坏”,变量消失了。在下一个循环中,将创建一个新的作用域,并且可以在该作用域中再次声明该变量。 由