This is the follow up of my question here: Weird Java generic.
If I have a code like this:
Casts.<X, T> cast(iterable[index]);
Can I add a static import and do:
<X, T> cast(iterable[index]);
Eclips开发者_如何学Ce doesn't allow this. But after seeing so many bugs with static import in Eclipse, I'm not that certain.
No, you can't : I just confirmed this via some test code.
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);
}
}
No
If you want to provide an explicit type parameter when calling a generic static method, you must prefix the method with the class name, even if the method is statically imported.
Java grammar allows type arguments only with typename specified. See corresponding section in JLS https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-MethodInvocation
I'm pretty sure the answer is no--if you want to use a generic method call, you need an object to call it on (foo.<T>doSomething()
). If the method is static, you need the class ( Foo.<T>doSomething()
).
This is even true if you're calling the method from elsewhere in the class itself. If you are working in a non-static method (i.e. in an instance method), you would call this.<T>doSomething()
.
As far as I've read, a shortcoming of the static import mechanism is that you must specify the calling object/class if you wish to provide formal parameters. In this example, it's not very clear why there are two generic parameters, but if you wish to avoid having to specify the calling object/class you can type hint through a cast of the arguments as such:
public static <E> E foo(E e) {}
Number n = foo((Number)3);
With the type hint, the type inference will return an object of type Number, instead of Integer as it would have reasoned otherwise.
精彩评论