Вызов статически импортированного метода с явными параметрами типа
Это продолжение моего вопроса здесь: Weird Java generic.
Если у меня есть такой код:
Casts.<X, T> cast(iterable[index]);
Можно добавить статический импорт и сделать:
<X, T> cast(iterable[index]);
Eclipse этого не допускает. Но, увидев так много ошибок со статическим импортом в Eclipse, я не уверен.
Ответы
Ответ 1
Нет, вы не можете: я только что подтвердил это с помощью некоторого тестового кода.
PS > javac -version
javac 1.6.0_04
Casts.java
public class Casts
{
public static <From, To> To cast(final From object)
{
return (To)object;
}
}
Test.java
import static Casts.cast;
public class Test
{
public static void main(String[] args)
{
final Integer integer = new Integer(5);
// This one compiles fine.
final Number number = Casts.<Integer, Number>cast(integer);
// This one fails compilation:
// PS> javac Test.java
// Test.java:11: illegal start of expression
// final Number number = <Integer, Number>cast(integer);
// ^
// Test.java:11: not a statement
// final Number number = <Integer, Number>cast(integer);
// ^
final String string = <Integer, String>cast(integer);
}
}
Ответ 2
Нет
Если вы хотите указать явный параметр типа при вызове общего статического метода, вы должны префикс метода с именем класса, даже если метод статически импортирован.
Ответ 3
Насколько я читал, недостатком механизма статического импорта является то, что вы должны указать вызывающий объект/класс, если вы хотите предоставить формальные параметры. В этом примере не очень понятно, почему существуют два общих параметра, но если вы хотите не указывать вызывающий объект/класс, вы можете набирать подсказку посредством набора аргументов как таковых:
public static <E> E foo(E e) {}
Number n = foo((Number)3);
С подсказкой типа вывод типа возвращает объект типа Number, а не Integer, как это было бы иначе.
Ответ 4
Java-грамматика допускает аргументы типа только с указанным именем. См. Соответствующий раздел в JLS https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-MethodInvocation
Ответ 5
Я уверен, что ответа нет - если вы хотите использовать общий вызов метода, вам нужен объект для его вызова (foo.<T>doSomething()
). Если метод статичен, вам нужен класс (foo.<T>doSomething()
).
Это даже верно, если вы вызываете метод из другого места в самом классе. Если вы работаете в нестационарном методе (т.е. В методе экземпляра), вы вызываете this.<T>doSomething()
.