Java Generi c в методе с типом параметра функционального интерфейса - PullRequest
0 голосов
/ 27 января 2020

Я не могу понять, почему этот код не компилируется:

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 ) );
   }

}

Так что я получаю это на консоли:

..\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

Я ожидаю использовать дженерики для включения типа для лямбда по параметру метода.

Ответы [ 3 ]

5 голосов
/ 27 января 2020

Это должно быть:

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 принимает Function с универсальными c параметрами, поэтому вы не всегда можете вызвать его apply метод с аргументом String и ожидайте, что он вернет Long.

Вместо этого вы можете передать ему аргумент String и изменить его тип возвращаемого значения на U.

Конечно, этот код будет бросить NumberFormatException, так как вы не можете преобразовать это String в Long.

1 голос
/ 27 января 2020

Причина в том, что Long.valueOf() принимает только String или long. Из параметра типа T компилятор делает вывод, что Function принимает Object, он не допустит его, так как нет метода как Long.valueOf( Object ).

Возможно, вам придется изменить myMethod() к этой подписи:

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

Или это, которое может бросить NumberFormatException:

public static <T, U> Long myMethod( Function<String, U> methodParam ){ //Input  type parameter is explicit
    return (Long) methodParam.apply( "Today is happy day!" );
}
1 голос
/ 27 января 2020

Как следует из ответа Эрана, у вас есть 2 проблемы: в определении myMethod и при вызове метода.

1) Вы объявляете methodParam как функцию с типом ввода T и типом вывода U. И тогда в myMethod вы рассматриваете это так, как будто T - String, а U - Long. Это только то, как вы хотите вызвать метод, но компилятор ничего не знает о T и U на данный момент. Решение Erans для myMethod работает так, как myMethod возвращает значение типа U (вместо Long) и получает параметр типа T вместо вызова apply () со строкой.

2) Вызов myMethod () в основной метод: либо как в примере Erans, параметры типа неявно задаются вашими параметрами. В противном случае, если вам по какой-то причине вам нужно express явно, @ernest_k показал решение (также найдено здесь ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...