Search code examples
javalambdafunctional-interface

Java final string parameter is not marked as compile time error in lambda expression


Consider the following code:

public class Test {
  interface Changeable {
    void change(String s);
  }

  public static void main(String[] args) {
    Test t = new Test();
    Changeable c = (s) -> s = s + " World"; // Line 1
    final String str = "Hello";
    t.changeIt(str, c);  // Line 2
    t.changeIt(str, (s) -> s = s + " Hello");  // Line 3
    System.out.println(str);
  }

  public void changeIt(String s, Changeable c) {
    c.change(s);
  }
}

How is a final variable str in this case, able to satisfy the above lambda. Perhaps I'm interpreting the code wrong but it looks like the lambda expression is re-assigning the str variable. Running the code (and seeing that it compiles) obviously contradicts this, what am I missing?


Solution

  • Your expression is equivalent to:

    Changeable c = new Changeable() {
      void change(String s) {
        s = s + "World";
      }
    }
    

    But s is the local reference to the string, so reassigning s you are not changing the original str reference, just the local one.