Dan Dan - 1 year ago 44
Java Question

Local variable is allowed the same name as global variable?

I am aware in certain circumstances you can have a global variable and a local variable which have the same name such as

int i = 0;

public Something(int i) {
this.i = i;

However I am confused to why this works. My code looks a little like this

TableRowSorter dataSorter; //Global Variable

public void setUpTable() {
//Some Code
dataSorter = new TableRowSorter(table.getModel());
DefaultRowSorter dataSorter = (DefaultRowSorter) table.getRowSorter(); //Local Variable
//Some More Code

Why is the
allowed to have the same variable name as

Answer Source

In your first example:

Your outer i is not a "global variable," it's an instance property (sometimes called an instance variable).

The code in your first example works because when you use an unqualified symbol, the one with the narrowest scope is chosen. (The one declared "closest" to the code using it.) So the unqualified i in your Something constructor is the i parameter, and you have to use this to access your instance field. Gory details in JLS§ Simple Expression Names.

When there's no identifier with a narrower scope, you can omit this. to access fields (and methods), but not when there's a conflicting identifier with narrower scope.


class Example {
    private int a;
    private int b;

    Example(int a) {
        // These work:
        this.a = a;
        this.b = 42;

        // This also works and does the same thing as `this.b = 42;`
        b = 42;

        // This fails to set the instance field `a`, because it assigns the value
        // of the `a` parameter to...the `a` parameter
        a = a; // Doesn't do what one probably wanted

In your second example:

You can successfully leave this. off the assignment to the instance field at the top of the method because you haven't declared your local variable yet. In Java, a variable declaration doesn't take effect until it's reached (unlike, say, old-style JavaScript where var gets hoisted).

So until the DefaultRowSorter dataSorter = ... line, when you use dataSorter unqualified, it refers to the instance field. After that, it refers to the local variable:

public class Example {
    private int a;

    public static final void main(String[] args) {
        new Example().go();;

    Example() {
        this.a = 42;

    void go() {
        System.out.println(a);      // 42, `a` is resolved to the instance field
        int a = 67;
        System.out.println(a);      // 67, `a` is resolved to the local because it
                                    // is "closer" to this code
        System.out.println(this.a); // 42, because we qualified it

Obviously I'd strongly recommend against doing that on purpose, but I'm sure you were already planning not to. :-)