【问题标题】:Java scope of a variable变量的Java范围
【发布时间】:2014-07-14 08:45:08
【问题描述】:

我不明白为什么这段代码的输出是10

package uno;

public class A
{
    int x = 10;
    A(){int x = 12; new B();}
    public static void main(String args[]){
        int x = 11;
        new A();
    }
    class B{
        B(){System.out.println(x);}
    }
}

此示例中的作用域如何工作?为什么System.out.println(x); 打印 10?是不是因为指令 System.out.println(x); 不在 costructor 的括号内:A(){int x=12; new B();} 所以 int x = 12 只存在于那里,但当 System.out.println(x); 被调用时,x = 12 不再存在?那么第一个x 是在A 类中声明的x=10?如果A 类中有x 怎么办?它会打印11吗?

【问题讨论】:

  • 如果 A 类中有 x 怎么办? x A 中。
  • 您正在 A() 中创建另一个变量,并且您没有修改该字段。在 A() 中尝试 x = 12。

标签: java scope


【解决方案1】:

局部变量只能在它们被声明的方法中被访问。考虑到这一点,可以重写代码以避免shadowing the member variables 和由此产生的混乱:

package uno;
public class A{
  // And instance member variable (aka field)
  int field_A_x = 10;
  A(){
    // A local variable, only visible from within this method
    int constructor_x = 12;
    new B(); // -> prints 10
    // Assign a new value to field (not local variable), and try again
    field_A_x = 12;
    new B(); // -> prints 12
  }
  public static void main(String args[]){
    // A local variable, only visible from within this method
    int main_x = 11;
    new A();
  }
  class B{
    B(){
      // The inner class has access to the member variables from
      // the parent class; but the field not related to any local variable!
      System.out.println(field_A_x);
    }
  }
}

(隐藏的成员变量始终可以在 this.x 表示法中访问;但我建议不要隐藏变量 - 选择有意义的名称。)

【讨论】:

    【解决方案2】:
    int x = 10;
    

    This 具有实例范围,A 类的任何成员都可以“看到”this。 B班看到了。

    int x=12;
    

    这具有本地范围,在您的 A 构造函数中。只在A的构造函数内部可见。

    int x = 11; 
    

    还有本地作用域,这次是在你的 main 方法中。

    System.out.println(x); 是谁? B 的构造函数。B 看到了什么? int x = 10;。 这就是为什么...

    此外,

    public class A{
      int x = 10;
      A(){int x=12; new B(); System.out.println(x); //prints 12}
      public static void main(String args[]){
        int x = 11;
        System.out.println(x); // prints 11
        new A();
      }
      class B{
        B(){System.out.println(x); //prints 10, as in your example}
      }
    }
    

    【讨论】:

    • 它当然没有全局范围。它的作用域是类 A 的实例。Java 中没有全局作用域。
    • 我的错。错误的术语用法。谢谢!
    【解决方案3】:

    试试如果您在第 4 行中省略 int 会发生什么:

    package uno;
    public class A{
      int x = 10;
      A(){x=12; new B();}
      public static void main(String args[]){
        int x = 11;
        new A();
      }
      class B{
        B(){System.out.println(x);}
      }
    }
    

    那么输出会是12,因为你没有初始化一个新的int x

    【讨论】:

      【解决方案4】:

      你的内部类看不到你在 A 类的构造函数中定义的局部变量。这就是 B 的 x 为 10 的原因。

      编辑:忍者

      【讨论】:

        【解决方案5】:

        如果您希望输出为 x=12,只需更改

        A(){int x=12; new B();}  // remove int here
        

        A(){x=12; new B();} 
        

        它当前正在创建一个local variable,因为它是在一个方法中声明的。

        删除构造函数中的新声明,将改变instance variable的值。

        所以输出将是x=12

        【讨论】:

          【解决方案6】:

          正在发生的是可变阴影。检查http://en.wikipedia.org/wiki/Variable_shadowing

          如果在本地方法中声明并初始化了同名变量,则该值仅在定义它的方法中使用。它不会更改全局变量变量。所以设置int x = 11int x = 12 不会改变x 的全局值。但是在一个方法中,如果未定义变量,则使用全局值,因此在类 B 中打印 x 的全局值。

          【讨论】:

            猜你喜欢
            • 2011-06-01
            • 2017-02-13
            • 2021-07-15
            • 2014-03-02
            • 2017-02-17
            • 1970-01-01
            • 2022-10-17
            • 1970-01-01
            • 2015-09-08
            相关资源
            最近更新 更多