tags:

views:

196

answers:

4

This is the follow up of my question here: http://stackoverflow.com/questions/2050202/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]);

Eclipse doesn't allow this. But after seeing so many bugs with static import in Eclipse, I'm not that certain.

A: 

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().

Matthew Flynn
almost everything in this answer is incorrect1) You can definitely call static methods without using the class if the method is statically imported2) You can call static methods on an object or a class, though the former is considered a bad practice3) You do not need to prefix a static method with the class name within a class
Don
Yes, you can if you are not declaring the casting class within the generic brackets <>. If you do want to declare the cast, you need an object. Show me it working without.
Matthew Flynn
A: 

The answer to your question was actually posted in the link to your other question. http://stackoverflow.com/questions/590405/generic-method-in-java-without-generic-argument/590418#590418

jcm
sorry, I don't see any answer of my question there.... Can you point it more specifically?
nanda
A: 

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.

Don
+1  A: 

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);
    }
}
jdmichal
I tried something similar with the same results. But I can't find anything in the JLS that suggests that the second form *should* be invalid.
Dan Dyer
Thanks! Just one suggestion, it will be better if the method cast is implemented like this: public <From, To extends From> To cast(final From object)I discussed it here:http://satukubik.com/2010/01/06/java-tips-using-generic-correctly/
nanda
Yea... I don't know WHY specifying the generic parameters causes this to happen. Just know experimentally that it does. I think static imports are the devil anyway, so I would never have known this otherwise. :)
jdmichal
@nanda Yes, that would be a better specification, as it prevents the possibility of a run-time `ClassCastException`, generating a compiler error instead.
jdmichal
@nando Note that `From` needs to extend `To` though. I tried specifying it as `<From, To super From>`, but the compiler does not like that so much. It does accept `<To, From extends To>` though.
jdmichal
@Dan Dyer: you must search the JLS to find if it is valid: JLS-15.12 shows what is accepted
Carlos Heuberger
@jdmichal: I think you're wrong... <To, From extends To> means there is no casting at all (from subtype to supertype, always correct), <From, To extends From> means casting (from supertype to subtype, may still wrong, which is the essence of casting).
nanda
@nanda Ah. I only accounted for up-casting, not down-casting. (It's still casting, even if there's no chance of error.) You would need to make both up-cast and down-cast methods to accommodate both situations using parameter wildcards.
jdmichal