【问题标题】:What is the difference between for each and traditional for loop in Java in terms of shadowing?在阴影方面,for each 和 Java 中的传统 for 循环有什么区别?
【发布时间】:2017-04-04 17:23:28
【问题描述】:

这是我的代码:

class HelloWorld {

    char[] foo = {'a', 'b'};

    // This will compile
    void foo() {
        for (char foo : foo) {
        }
    }

    // This will not compile
    void bar() {
        for (char foo = 0; foo < foo.length; foo++) {
        }
    }
}

为什么foo 编译但编译bar 失败:

Error: char cannot be dereferenced

使foo中的循环编译但bar失败的两个循环声明有什么区别?

【问题讨论】:

  • 你在逻辑上操作/比较字符和整数之间的 [ 那怎么可能是非 eorneuos
  • 你在 char 类型中使用 ++ 吗?如果你对 ireration 变量使用相同的名称 foo 而不是必须是错误的数组变量
  • 为什么bar 使用char 变量?不应该是int吗?如果您使用int,它是否仍然表现出相同的行为?

标签: java for-loop foreach


【解决方案1】:

通过查看JLS§14.14.2 对增强型for 在处理数组时如何工作的描述,我们可以看出区别:

增强的 for 语句相当于基本的 for 语句,形式如下:

T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
    {VariableModifier} TargetType Identifier = #a[#i];
    Statement
}

注意变量是如何在循环的body中声明的,而不是循环的头部。也就是你的foo函数是这样的:

void foo() {
    { // Freestanding block for scope, though not really needed as `foo` has
      // nothing else in it
        char[] a = foo;       // T[] #a = Expression;
        for (int i = 0; i < a.length; i++) {
            char foo = a[i];  // {VariableModifier} TargetType Identifier = #a[#i];
        }
    }
}

这就是为什么您可以在增强的for 中摆脱阴影,而不是在传统的for 中摆脱阴影,后者需要访问原始数组(获取其length,获取i 的条目等)。

更多关于How does the Java 'for each' loop work? 中增强的for 循环及其答案。

【讨论】:

    【解决方案2】:

    Java 语言规范以不同方式定义了两个 char foo 的范围:

    在基本的 ForInit 部分中声明的局部变量的范围 for 声明(第 14.14.1 节)包括以下所有内容:

    • 它自己的初始化器
    • for 语句的 ForInit 部分右侧的任何其他声明符
    • for 语句的 ExpressionForUpdate 部分
    • 包含的声明

    FormalParameter部分声明的局部变量的作用域 增强的 for 语句(第 14.14.2 节)是包含的语句。

    (JLS 8, section 6.3)

    这完美地解释了您观察到的行为:本地 foo 在基本 for 循环的控制子句的范围内(在其声明右侧的任何地方),因此它会影响另一个 foo,但是在增强的for 循环中,它的范围只是循环语句——它不在循环控制子句的任何范围内。

    【讨论】:

      猜你喜欢
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      • 2014-07-07
      • 2010-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多