13

I hava a problem about Java 8 Runnable.

 public static void main(String[] args) {
    Runnable r1 = Test::t1;
    Runnable r2 = Test::t2;
    Runnable r3 = Test::t3;
}

public static void t1() {

}

public static String t2() {
    return "abc";
}

public static String t3(String t) {
    return t;
}

As the code show, I understand r1 is right and r3 is wrong, but I don't understand why r2 is also right. Can anybody help me understand it?

Lii
  • 11,553
  • 8
  • 64
  • 88
yi jiang
  • 216
  • 1
  • 13
  • @YassinHajaj Huh, you are right! Sorry, my fail :) – Hrabosch Jun 30 '16 at 09:18
  • @Hrabosch No problem :) – Yassin Hajaj Jun 30 '16 at 09:19
  • @Hrabosch,r3 is wrong , i just don't understand why r2 is right – yi jiang Jun 30 '16 at 09:19
  • @yijiang I think because that you call method reference to static method without parameter, so i dont know why there should be a problem. Do you know what i mean? – Hrabosch Jun 30 '16 at 09:33
  • @Hrabosch, as we all know, the Runnable's run method is without param and return type, but t2() in my code has the return type, so i don't know why it can be assigned to Runnable r2 – yi jiang Jun 30 '16 at 09:49
  • @yijiang Yes, but in think, in this case you are calling second method without parameter (what is correct) and about returning value there is rule which is described in answer, in this case is ignored return value – Hrabosch Jun 30 '16 at 10:25

1 Answers1

19

r2 is fine due to section 15.13.2 of the JLS, which includes:

A method reference expression is congruent with a function type if both of the following are true:

  • The function type identifies a single compile-time declaration corresponding to the reference.

  • One of the following is true:

    • The result of the function type is void.
    • The result of the function type is R, and the result of applying capture conversion (§5.1.10) to the return type of the invocation type (§15.12.2.6) of the chosen compile-time declaration is R' (where R is the target type that may be used to infer R'), and neither R nor R' is void, and R' is compatible with R in an assignment context.

Basically, it would be valid to write t2(); and just ignore the return value, so it's valid to create a method reference which calls the method and ignores the return value.

t3 isn't valid, because you have to provide a parameter, and Runnable doesn't take a parameter, so there'd be nothing to "pass on" to the method.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194