0

I cannot figure out why this code don't compile :

package Desktop;

import java.util.function.*;

public class MyClass {

    public static <T, U> Long myMethod( Function<T, U> methodParam ) {
      return methodParam.apply("Today is happy day!");
    }

   public static void main(String[] args) {
      System.out.println( <String, Long>myMethod( Long::valueOf ) );
   }

}

So i receive this on console:

..\Desktop\MyClass.java:15: error: illegal start of expression
          System.out.println( <String, Long>myMethod( Long::valueOf ) );
                                            ^
..\Desktop\MyClass.java:15: error: ';' expected
          System.out.println( <String, Long>myMethod( Long::valueOf ) );
                                                                     ^
2 errors

I am expecting to use generics to include type for the lambda on method parameter.

marcius.tan
  • 97
  • 1
  • 7

3 Answers3

5

It should be:

public static <T, U> U myMethod(Function<T, U> methodParam, T t) {
  return methodParam.apply(t);
}

public static void main(String[] args) {
   System.out.println(myMethod(Long::valueOf, "Today is happy day!") );
}

myMethod accepts a Function with generic parameters, so you can't always call its apply method with a String argument and expect it to return a Long.

Instead, you can pass to it the String argument, and change its return type to U.

Of course, this code will throw a NumberFormatException, since you can't convert that String to a Long.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • 2 Errors generated by it. – marcius.tan Jan 27 '20 at 08:15
  • @marcius.tan that's strange. I compiled and executed this code. It throws an exception, as I said, but it passes compilation. – Eran Jan 27 '20 at 08:19
  • public static U myMethod( Function methodParam, T t ) { return methodParam.apply(t); } public static void main(String[] args) { Long ddd = myMethod( Long::valueOf, "today is a good day!"); System.out.println(ddd); } – marcius.tan Jan 27 '20 at 08:22
  • my recent reply compiles but .class interpret throws java.lang.NumberFormatException: For input string: "today is a good day!" – marcius.tan Jan 27 '20 at 08:24
  • @marcius.tan As I said, it's not a surprise this code throws an exception. – Eran Jan 27 '20 at 08:28
  • I'll try to think about it again in next days. I think i am lacking the fundamental here. Thx for all the respond. I appreciate! – marcius.tan Jan 27 '20 at 08:30
  • 1
    @marcius.tan What don't you understand? Are you surprised that `Long.valueOf("Today is happy day!")` throws an exception? – Eran Jan 27 '20 at 08:32
  • OMG! this is what happens when i got stuck for extended time. I put "168" at the beginning but then i changed to "today is a good day!". Now, after "168" it compiles + interpret fine! god*mn!.. – marcius.tan Jan 27 '20 at 08:37
1

As Eran's answer suggests, you have 2 problems: In the definition of myMethod and in the call of the method.

1) You declare methodParam as a function with input type T and output type U. And then in myMethod you treat it as if T was String and U was Long. This is only how you want to call the method but the compiler does not know anything about T and U at this point. Erans solution for myMethod works as myMethod returns a value of type U (instead of Long) and receives a parameter of type T instead of calling apply() with a string.

2) The call of myMethod() in the main method: either as in Erans example the type parameters are implicitly given by your parameters. Otherwise, if you need to express them explicitly for some reason, @ernest_k showed the solution (also found here).

1

The reason is that Long.valueOf() takes only either String or long. From the type parameter T, the compiler concludes that the Function takes Object, it will not allow it since there is no method as Long.valueOf( Object ).

You may have to change myMethod() to this signature:

public static <T, U> Long myMethod( Function<String, Long> methodParam ) { //Both type parameters are explicit
    return methodParam.apply("Today is happy day!");
}

Or this, which may throw NumberFormatException:

public static <T, U> Long myMethod( Function<String, U> methodParam ){ //Input  type parameter is explicit
    return (Long) methodParam.apply( "Today is happy day!" );
}
Sree Kumar
  • 2,012
  • 12
  • 9