Search code examples
javainner-classesouter-classes

Must an inner class use 'this' keyword in order to use outer class method or attributes?


I'm reading the source code of ArrayList and this class has an inner class with the name SubList. I'm looking in a method of the inner class (SubList) and see the following methods:

 public E set(int index, E e) {
        rangeCheck(index);
        checkForComodification();
        E oldValue = ArrayList.this.elementData(offset + index);
        ArrayList.this.elementData[offset + index] = e;
        return oldValue;
    }

What I see that line 3 & 4 uses this keyword in order to call/use ArrayList (outer class) method/attribute. I want to understand is it must to use OuterClass.this or elementData() will be enough? I run an example long ago (more than a year) and I was able to call an outer class method from an inner class without using this keyword.


Solution

  • There is a Shadowing problem that can lead to unexpected behavior and runtime errors.

    If a declaration of a type (such as a member variable or a parameter name or method name) in a particular scope (such as an inner class or a method definition) has the same name as another declaration in the enclosing scope, then the declaration shadows the declaration of the enclosing scope. You cannot refer to a shadowed declaration by its name alone.

    public class ShadowTest {
    
        public int x = 0;
    
        class FirstLevel {
    
            public int x = 1;
    
            void methodInFirstLevel(int x) {
                System.out.println("x = " + x);
                System.out.println("this.x = " + this.x);
                System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
            }
        }
    
        public static void main(String... args) {
            ShadowTest st = new ShadowTest();
            ShadowTest.FirstLevel fl = st.new FirstLevel();
            fl.methodInFirstLevel(23);
        }
    }
    

    Output:

    x = 23
    this.x = 1
    ShadowTest.this.x = 0
    

    As you can see, to get the correct value of higher scope, you need to use only ShadowTest.this.

    Thru time your code will mutate and you can miss the same name in the other scope, so you must use only OuterClass.this to access outer class scope, make code clear and bulletproof.

    See the Java Tutorial.