在Java中命名两种作用域

在Java中命名两种作用域,java,c++,scope,Java,C++,Scope,我在命名Java中看到的两种作用域时遇到困难: class Fun { int f = 1; void fun() { int f = 2; while(true){ int f = 3; int g = 1; } int g = 2; } } 这种情况多为f=3和g=2 while语句不会引入新的作用域,因此我无法创建名为f的while局部变量。但是如果我创

我在命名Java中看到的两种作用域时遇到困难:

class Fun {
    int f = 1;
    void fun() {
        int f = 2;
        while(true){
            int f = 3;
            int g = 1;
        }
        int g = 2;
    }
}
这种情况多为
f=3
g=2

while
语句不会引入新的作用域,因此我无法创建名为
f
的while局部变量。但是如果我创建一个名为
g
的局部变量,那么我可以在循环之后“重新创建”它。为什么?我知道它不再可访问,但是如果编译器检查可访问性,那么它几乎会检查作用域

所以我想知道这里的交易是什么,这些概念叫什么?它与C++中的相同吗?< /P>
我刚刚设法安装了g++并亲自进行了尝试:

#include <iostream>
using namespace std;

int main(){
    int f = 0;
    for(int i=0; i<1; i++){
        int f = 1;
        cout << f << endl;
        {
            int f = 2;
            cout << f << endl;
        }
    }
    cout << f << endl;
}
#包括
使用名称空间std;
int main(){
int f=0;

对于(inti=0;i一旦你离开while{}循环,g就在你离开它的时候离开了作用域。然后再次声明g是有效的

局部变量仅在声明它们的块的持续时间内处于作用域内

更详细地说:

  • 第一个
    f
    是对象范围。它完全可以从对象访问 时代
  • 第二个
    f
    是本地作用域。您可以使用
    f
    访问它 仍然可以使用
    this.f
    访问对象范围
    f
  • 第三个
    f
    正在尝试创建第二个本地作用域
    f
    。这是无效的

  • 第一个
    g
    是创建一个本地作用域
    g

  • 第二个
    g
    正在创建第二个本地作用域
    g
    ,但第一个已超出作用域并消失
所以唯一无效的声明是第三个f

第三种类型的作用域是声明静态变量的地方——这些变量在类的每个实例之间共享

类型有很多名称,其中一些最常见的是局部变量、实例变量(也称为字段)和类变量(也称为静态字段)。也有方法参数,但这只是获取局部变量的不同方式

进一步阅读:


    • 在java中,禁止从外部局部作用域IIRC对变量进行阴影处理。这只是“任意”的语言规则,以防止程序员犯一些愚蠢的错误。C#有相同的规则IIRC,甚至更严格(最后一个
      g
      在C#中可能是错误的,因为它在同一方法的作用域中,不确定)C和C++没有这个规则,虽然通常有编译器警告,这取决于编译器和警告标志。 每个
      {}
      都是一个新的块范围

      最后一个
      g
      不会对较早的
      g
      产生阴影,因为较早的一个已不在范围内。因此这是正常的

      最里面的
      f
      阴影是早期的本地
      f
      ,它仍在范围内,因此不正常


      类成员变量仍然可以通过使用
      this来访问。
      因此可以对它们进行阴影处理(尽管可能会产生误导,特别是如果IDE语法高亮显示没有以不同方式高亮显示它们)。

      块中局部变量声明的范围是声明出现的块的其余部分(JLS 6.3声明的范围)


      while循环引入了一个新的作用域,它可以看到它上面的所有东西,上面的东西看不到它。每个{引入了一个新的作用域,包括while语句之后的那些。好吧,那么为什么我可以在一个方法中重新声明
      f
      (有一个实例
      f
      ),而我不能在一个循环中呢?@user基本上是因为这样做;使上一个f无法到达(而使用this.f可以访问隐藏字段)并且它很容易引起令人惊讶的bugsAh…所以您要说的是Java中有两种作用域:object和local(这些是专有名称吗?)此外,只有类声明创建对象范围。我能正确理解吗?比如,C++中的内容是否相同?我将再加一点:)我非常喜欢你的第一句话,很清楚,指出了任意性……你知道其他语言(C++、JavaScript…)是如何处理的吗?另外,你知道官方名字(如果它们存在的话)吗?对于这两种作用域?@user3073853我必须找出JLS来获得正式名称,但这听起来可以理解:方法的方法作用域和{}compund语句的块作用域。根据需要添加“嵌套”或“内部”/“外部”来定义作用域关系。@user3073853了解确切术语的肮脏细节…:-)
      class Fun {
          int f = 1;// Its My f and i wont tell my fun() not to have 'f'
          void fun() {
              int f = 2; //Its my 'f' and till i own my 'f' i wont consider Fun Class 'f' also while 'f' 
              while(true){
                  int f = 3; //Its my 'f' and he rules within me alone 
                  int g = 1;
              }
              int g = 2;
          }
      }
      
      void fun() {  // block starts
      
         int f = 2; // f will be visible everywhere from fun() body
      
      ...
      
         {  // another block starts, it's legal even without while or for
            // f is visible, you cannot declare it again
      
            int g = 1; // will be visible till the end of the block
      
         }
      
         // g is invisible here because the block where it was declared ended
      }