Предоставление параметра типа ссылке на метод Java 8

#java #java-8

#java #java-8

Вопрос:

У меня есть класс со статическим методом, подобным следующему:

 public class Foo {
  public static <T> T foo() {
    // do something
  }
}
  

Если бы я хотел вызвать Foo.foo и убедиться, что возвращаемый тип был T , я мог бы сказать Foo.<T>foo() . Как я могу сделать то же самое для ссылки на метод Foo::foo ? Я пробовал Foo::<T>foo , но это, похоже, недопустимый синтаксис.

Комментарии:

1. Что заставляет вас думать, что это недопустимо?

2. @Sotirios intellij 13. Я знаю, что это означает, что это не обязательно недопустимая Java 8, потому что я видел много мест, где intellij сообщает о чем-то, использующем «новые» функции, как о недопустимом, но код компилируется с помощью javac. однако, к сожалению, поскольку код почти всегда будет редактироваться с помощью intellij, я ограничен тем, что он будет принимать.

3. Что говорит или показывает intellij? Для какого кода?

4. @SotiriosDelimanolis если то, что я написал, является правильным способом выразить это, и это просто несоответствие javac intellij, пожалуйста, опубликуйте это в качестве ответа, и я задам новый вопрос об intellij.

5. Вы могли бы просто поместить все детали здесь, т. Е. Сообщения об исключениях, фактический код и т.д., И мы можем помочь вам прямо сейчас.

Ответ №1:

Форма Type::<Arg>name является допустимым синтаксисом, но вы должны ввести конкретный тип в аргумент. Вне метода foo() нет типа T , поэтому конкретное выражение Foo::<T>foo не будет работать, если у вас нет другого T в области видимости.

Однако обратите внимание, что в большинстве случаев нет необходимости указывать аргумент типа вообще. Это будет выведено из контекста:

 public class Foo {
  public static <T> T foo() {
    // do something
    return null;
  }
  // you can specify type arguments
  static Supplier<String> S0=Foo::<String>foo;
  static Supplier<Integer> I0=Foo::<Integer>foo;
  // but there is no need for it:
  static Supplier<String> S1=Foo::foo;
  static Supplier<Integer> I=Foo::foo;
}
  

Но обратите внимание, что такой метод, как public static <T> T foo() , не имеет реального смысла. Поскольку реализация метода не имеет возможности определить, какой тип ожидает вызывающий, T единственное значение, которое он может вернуть, это null . Хорошо, это может иметь смысл, если оно действует только как заполнитель.