Не существует такой вещи, как «необработанная ссылка на метод». Несмотря на то, что необработанные типы существуют для облегчения миграции кода, предшествующего Generics, не может быть никакого использования ссылок на методы до Generics, поэтому не существует «режима совместимости», и вывод типов является нормой. Спецификация языка Java §15.13. Справочные выражения методов указывают:
Если метод или конструктор является универсальным, соответствующие аргументы типа могут быть либо выведены, либо предоставлены явно. Точно так же аргументы универсального типа, упомянутые в выражении ссылки на метод, могут быть предоставлены явно или выведены.
Выражения ссылок на методы всегда являются поливыражениями.
Таким образом, хотя вы можете называть тип перед ::
«необработанным типом», когда он ссылается на универсальный класс без указания аргументов типа, компилятор все равно выведет сигнатуру универсального типа в соответствии с типом целевой функции. Поэтому выдавать предупреждение об «использовании необработанных типов» здесь не имеет смысла.
Обратите внимание, что, например.
BiFunction<List<String>,Integer,String> f1 = List::get;
Function<Enum<Thread.State>,String> f2 = Enum::name;
может быть скомпилирован с javac
без каких-либо предупреждений (в спецификации указаны похожие примеры, где тип должен быть выведен), тогда как
Function<Thread.State,String> f3 = Enum::name;
генерирует предупреждение. спецификация говорит об этом случае:
При втором поиске, если P1
, ..., Pn
не пусто и P1
является подтипом ReferenceType, то выражение ссылки на метод обрабатывается так, как если бы оно было выражением вызова метода с выражениями аргументов типы P2
, ..., Pn
. Если ReferenceType является необработанным типом и существует параметризация этого типа, G<...>
, которая является супертипом P1
, тип для поиска является результатом преобразования захвата (§5.1.10), примененного к G<...>
;…
Таким образом, в приведенном выше примере компилятор должен вывести Enum<Thread.State>
как параметризацию Enum
, которая является супертипом Thread.State
, чтобы найти подходящий метод и прийти к тому же результату, что и в примере f2
. Каким-то образом это действительно работает, хотя и генерирует бессмысленное предупреждение необработанного типа.
Поскольку, по-видимому, javac
генерирует это предупреждение только тогда, когда ему нужно искать подходящий супертип, для вашего случая есть простое решение. Просто используйте точный тип для поиска:
public static <T extends Enum<T>> ColumnType<T, String> enumColumn(Class<T> klazz) {
return simpleColumn((row, label) -> valueOf(klazz, row.getString(label)), T::name);
}
Это компилируется без каких-либо предупреждений.
person
Holger
schedule
12.05.2016