在Java中命名两种作用域
我在命名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局部变量。但是如果我创
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
}