Reputation: 365
I have difficulties in naming the two kinds of scopes that I see in Java:
class Fun {
int f = 1;
void fun() {
int f = 2;
while(true){
int f = 3;
int g = 1;
}
int g = 2;
}
}
The case is mostly with f = 3
and g = 2
;
A while
statement doesn't introduce a new scope, so I can't create a while-local variable named f
. But if I create a local variable named g
then I can "re-create" it after the loop. Why? I know it's no longer accessible, but if the compiler checks accessibility then it almost checks scopes..
So I was wondering what is the deal here, what are these concepts called? Is it the same as in C++?
I just managed to install g++ and tried it out myself:
#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;
}
So apparently C++ treats all scopes equally!
Upvotes: 11
Views: 214
Reputation: 62908
In java it is forbidden to shadow variables from outer local scopes, IIRC. It's just "arbitrary" language rule, to prevent programmer from making some stupid mistakes. C# has same rule, IIRC, or even more strict (the last g
might be error in C# because it was in scope in same method, not sure). C and C++ do not have this rule, though usually there is a compiler warning, depending on compiler and warning flags.
Every {}
is a new block scope.
The last g
does not shadow the earlier g
because earlier one is not in scope any more. So it's ok.
The innermost f
shadows the earlier local f
which is still in scope, so not ok.
Class member variables are still accessible by using this.
so it's ok to shadow them (though potentially misleading, esp. if IDE syntax highlighting does not highlight them differently).
Upvotes: 3
Reputation: 136112
The scope of a local variable declaration in a block is the rest of the block in which the declaration appears (JLS 6.3 Scope of a Declaration).
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
}
Upvotes: 0
Reputation: 41208
Once you left the while{} loop g went out of scope as soon as you left it. It was then valid to declare g again.
Local variables are only in scope for the duration of the block in which they are declared.
To go into more detail:
f
is object scope. Its accessible from the object at all
times. f
is local scope. You access it using f
, you
can still access the object scope f
using this.f
. The third f
is trying to create a second local scope f
. That is invalid.
The first g
is creating a local scope g
.
g
is creating a second local scope g
but the first one has already gone out of scope and disappeared.So the only invalid declaration is the third f.
There is a third type of scope which is where static variables are declared - these are variables that are shared between every instance of a class.
There are a number of names for the types, some of the most common are Local Variables, Instance Variables (also known as Fields) and Class Variables (also known as Static Fields). You also have method parameters but that's just a different way of getting a Local Variable.
For further reading:
Upvotes: 5
Reputation: 2486
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;
}
}
Upvotes: 0