Mehod Local Inner Class Example..

.. with some notes!

It is one of these days and I am studying this book, and stumbled upon the following passage, and wanted to experience it myself!
A method-local inner class can be instantiated only within the method where the inner class is defined. Like regular inner class objects, the method-local inner class object shares a special relationship with the enclosing (outer) class object and can access its private (or any other) members. However, the inner class object cannot use the local variables of the method the inner class is in.
Think about it. The local variables of the method live on the stack and exist only for the lifetime of the method. You already know that the scope of a local variable is limited to the method the variable is declared in. When the method ends, the stack frame is blown away and the variable is history. But even after the method completes, the inner class object created within it might still be alive on the heap if, for example, a reference to it was passed into some other code and then stored in an instance variable. Because the local variables aren't guaranteed to be alive as long as the method-local inner class object is, the inner class object can't use them. Unless the local variables are marked final!

Example

OuterClass.java
public class OuterClass {
 
    private int foo = 42;
 
    private OuterClass myInner_01;
    private OuterClass myInner_02;
 
    public void foo() {
 
        int baz = 900;
 
        final class MethodInnerClass extends OuterClass {
            private int foo;
 
            public void incrementOuterFoo() {
                OuterClass.this.foo++;
            }
 
            public void bar() {
                System.out.println("Bar method in MethodInnerClass");
            }
        }
 
        final MethodInnerClass mic_01 = new MethodInnerClass();
        mic_01.setFoo(foo);
        mic_01.incrementOuterFoo();
 
        myInner_01 = mic_01;
 
        final MethodInnerClass mic_02 = new MethodInnerClass();
        mic_02.setFoo(foo);
        mic_02.incrementOuterFoo();
 
        myInner_02 = mic_02;
    }
 
    public int getFoo() {
        return foo;
    }
 
    public void setFoo(int val) {
        foo = val;
    }
 
    public OuterClass getMyInner_01() {
        return myInner_01;
    }
 
    public OuterClass getMyInner_02() {
        return myInner_02;
    }
 
    public void bar() {
        System.out.println("Bar method in OuterClass");
    }
}

App.java
public class App {
 
    public static void main(String[] args) {
        final OuterClass oc = new OuterClass();
        oc.foo();
        System.out.println("OuterClass foo: " + oc.getFoo());
 
        final OuterClass inner_01 = oc.getMyInner_01();
        System.out.println("Inner_01 foo: " + inner_01.getFoo());
 
        final OuterClass inner_02 = oc.getMyInner_02();
        System.out.println("Inner_02 foo: " + inner_02.getFoo());
 
        oc.bar();
        inner_01.bar();
        inner_02.bar();
    }
}

In Action..
MacBook-Pro:Desktop koraytugay$ javac App.java
MacBook-Pro:Desktop koraytugay$ java App
OuterClass foo: 44
Inner_01 foo: 42
Inner_02 foo: 43
Bar method in OuterClass
Bar method in MethodInnerClass
Bar method in MethodInnerClass

Notes

Imagine MethodInnerClass#bar was printing baz and in App.java we are calling inner_01.bar... What would it even print? The instance is living in the heap, and it has no access to baz anymore.. The method OuterClass#foo is long gone, nada, poof.. And why does it work if baz is final? I do not know..

Also note how MethodInnerClass is incrementing OuterClass#foo:
OuterClass.this.foo++;

Now, that is a syntax!