4

I am new in Java and came across one OCJA-1.8 sample question where I am having some doubt. I need clarification on this behavior of JVM.

 public class Test{

static int x=1;//**This is static class level variable**

   public static void main(String[] args){
    int[] nums={1,2,3,4,5};
    for(int x:nums){ // Local variable declared for for-each loop.
        System.out.println(x);
    }
  }
}

Why has the JVM not thrown an error for a duplicate variable for the variable which is declared inside for each loop 'int x'? As static variable has class level scope.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Gaurav Pathak
  • 2,576
  • 1
  • 10
  • 20

5 Answers5

4

The local variable hides the original static field somewhat, but it is not inaccessible:

Test.x

And for non-static fields:

this.x // not in this case

So it is allowed, and in effect one often sees:

public class Pt {
    private final int x;
    public Pt(int x) {
        this.x = x;
    }
}

Which prevents the need to introduce some convention (_x, mX).

What is not allowed:

void f() {
    int x = 42;
    if (true) {
        int x = 13; // COMPILER ERROR
        ...
    }
}

As this is bad style, causing confusion.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
2

The inner variable declaration of x override the static one. If you need to access the static variable you can access it with Test.x

hi olaf
  • 227
  • 1
  • 5
2

The duplicate variable compilation error happens for two variables with the same name declared in the same scope : fields or method declaration scope.
In your example, each variable is declared in a distinct scope.
As a consequence, as you refer x in the method declaring x, by default it refers to the variable with the nearer scope available (the x local variable) that so shadows the other variable (the x field variable).

To reference the shadowed variable :

  • if it is a static field (your case), prefix it with the class name declaring it : Test.x
  • if it is an instance field, prefix it with the this keyword : this.x
davidxxx
  • 125,838
  • 23
  • 214
  • 215
1

When you have a local variable same as static variable, static variable of the class is shadowed by the local variable.

Joicy
  • 9
  • 5
1

It doesn't throw an error because Java has the concept of shadowing. In essence, the variable with the lowest scope is used.

The static field is still accessible, you just need to fully qualify it:

for(int x:nums){
    System.out.println(x);       // Local x
    System.out.println(Test.x);  // static x
}

This can be confusing to a reader of your code and so should be avoided in most cases. If you find yourself with a field and local variable named identically, there's probably something up and you should re-evaluate how you've named your variables.

In your specific case, x is not a descriptive name and both variables would benefit from better, more descriptive names.

In certain cases, such as within a constructor or setter method, it's beneficial to have local variables and fields with the same names, and this is where shadowing is a useful feature.

Michael
  • 41,989
  • 11
  • 82
  • 128