Tom
Tom

Reputation: 6332

Can inner class refer non finalvariable defined in outer class in Java 8

I have always thought that an inner class CANNOT refer non final variable defined in outer class.

But, when I write the following code, it compiles correctly and can be run in Intellij Idea.

Why does the following code work?

public class Outer {

    /**
     * non final variable greeting is used in inner class, non final is OK?
     */
    private String greeting = "Greeting1";

    /**
     * non final variable s is used in inner class, non final is OK?
     */
    public String doWork(String s) {
        class Inner {
            public String speak(String ss) {
                return greeting + "--- " + s + "---" + ss;
            }
        }
        Inner obj = new Inner();
        return obj.speak("Inner");
    }

    public static void main(String[] args) {
        Outer obj = new Outer();
        //Can assign here.
        obj.greeting="Greeting2";
        System.out.println(obj.doWork("Outer"));
    }
}

Upvotes: 3

Views: 52

Answers (1)

Sweeper
Sweeper

Reputation: 271050

The Java Language Specification says:

Any local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

You most likely recalled/remembered an incorrect version of that. You might have mistook it as:

Any instance variable, local variable, formal parameter, or exception parameter used but not declared in an inner class must either be declared final or be effectively final (§4.12.4), or a compile-time error occurs where the use is attempted.

greeting is a field (aka instance variable), so can be used in inner classes whether or not it is final or not.

ss, though it is a formal parameter, is effectively final, so it can be used in inner classes too. Note that the phrase "effectively final" has a formal definition in §4.12.4, but informally, it just means "you did not reassign it another value in this method" in this context.

See this post for why this restriction exists.

Upvotes: 4

Related Questions