This will compile
class X
{
public static void main(String args[])
{
{
int a = 2;
}
{
int a = 3;
}
}
}
This won't
class X
{
public static void main(String args[])
{
int a = 2;
{
int a = 3;
}
}
}
I expected both to compile (maybe it is the way C works?). What is the reason because it is not possible to declare a variable in a block with the same name of one in the outer block?
Function Scope: When a variable is declared inside a function, it is only accessible within that function and cannot be used outside that function. Block Scope: A variable when declared inside the if or switch conditions or inside for or while loops, are accessible within that particular condition or loop.
The script declares a variable num within the local scope of a function and re-declares it within a block using the let keyword. The value of the locally scoped variable is printed when the variable is accessed outside the inner block, while the block scoped variable is referred to within the inner block.
Block scope means a variable was defined within a block of code, such as a for loop or an if statement. With these definitions out of the way, let's look at how these different scope levels affect a C++ program.
let is block-scoped In the above program, the variable a is declared inside the function and it can be accessed anywhere inside the function ( a becomes function scoped). However the variable b is declared inside the if block statement. b will be block-scoped and can only be accessed inside the if block.
The short answer is: Because this is the way the Java language is defined in JLS §6.4.
You might be used from other languages that this so called variable shadowing is allowed. However, the inventors of the Java languages thought this was an awkward feature that they did not want in their language:
This restriction helps to detect some otherwise very obscure bugs.
However, you find shadowing elsewhere in Java as the authors state in the same section of the JLS:
A similar restriction on shadowing of members by local variables was judged impractical, because the addition of a member in a superclass could cause subclasses to have to rename local variables. Related considerations make restrictions on shadowing of local variables by members of nested classes, or on shadowing of local variables by local variables declared within nested classes unattractive as well.
This means in practice that the following code is legal:
class A {
int x = 0;
void m() {
int x = 10; // Shadows this.x
}
}
As the authors describe, it is allowed to shadow an instance variable by declaring a method local variable with the same name because of the possibility of someone extending the functionality of A
at one day where you could not longer compile a class B
if shadowing was illegal:
class B extends A {
void m() {
int x = 10; // Shadows A.this.x if A declares x
}
}
If you consider a language like C, where shadowing is allowed, you can find awkward code like this:
int x;
int main()
{
{
int x = 0;
{
extern int x;
x = 1;
}
printf("%d\n", x); // prints 0
}
printf("%d\n", x); // prints 1
return 0;
}
This program is not so easy to follow and might therefore not produce the results you expect, thanks to variable shadowing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With