我在命名我在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-local变量。但是如果我创建一个名为g
的局部变量,那么我可以在循环之后“重新创建”它。为什么?我知道它不再可访问,但如果编译器检查可访问性,那么它几乎检查范围..
所以我想知道这里的交易是什么,这些概念叫做什么?它与C ++中的相同吗?
我刚刚设法安装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;
}
显然,C ++平等地对待所有范围!
答案 0 :(得分:5)
一旦你离开了{}循环,你离开它时就会超出范围。然后再次申报g是有效的。
局部变量仅在声明它们的块的持续时间范围内。
详细说明:
f
是对象范围。它可以从对象访问
倍。 f
是本地范围。您可以使用f
来访问它
仍然可以使用f
访问对象范围this.f
。 第三个f
正在尝试创建第二个本地范围f
。这是无效的。
第一个g
正在创建一个本地范围g
。
g
正在创建第二个本地范围g
,但第一个范围已经超出范围并消失。所以唯一无效的声明是第三个f。
第三种类型的范围是声明静态变量的地方 - 这些是在类的每个实例之间共享的变量。
这些类型有许多名称,其中一些最常见的是局部变量,实例变量(也称为字段)和类变量(也称为静态字段)。您还有方法参数,但这只是获取局部变量的另一种方式。
进一步阅读:
答案 1 :(得分:3)
在java中,禁止隐藏来自外部本地作用域IIRC的变量。它只是“任意”的语言规则,以防止程序员犯一些愚蠢的错误。 C#具有相同的规则,IIRC,甚至更严格(最后g
可能是C#中的错误,因为它在同一方法的范围内,不确定)。 C和C ++没有这个规则,但通常会有编译器警告,具体取决于编译器和警告标志。
每个{}
都是一个新的块范围。
最后g
不影响早期的g
,因为之前的f
不在范围内。所以没关系。
最里面的f
会影响仍然在范围内的早期本地this.
,所以不行。
仍然可以使用{{1}}访问类成员变量,因此可以隐藏它们(尽管可能会产生误导,特别是如果IDE语法突出显示不会突出显示它们)。
答案 2 :(得分:0)
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;
}
}
答案 3 :(得分:0)
块中局部变量声明的范围是声明出现的块的其余部分(JLS 6.3声明的范围)。
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
}