borzoni
borzoni

Reputation: 82

Unbounded wildcard passed to method

public class ColTest {
static<T> T wildSub(ArrayList<? extends T> holder, T arg){
        T t=holder.get(0);
        return t;
    }

    public static void main(String[] args) {
        ArrayList<?> list=new ArrayList<Long>(Arrays.asList(2L,3L,7L));
        Long lng=1L;
        ColTest.wildSub(list, lng);
    }
}

Really interested why this snippet is legal, because the signature of wildSub takes only ArrayList of T or derived from T, and arg of type T. But <?> means - some specific type, not known, and how it can satisfy the compiler? After all type <?> doesn't mean <? extends Long> ...

Upvotes: 3

Views: 185

Answers (4)

irreputable
irreputable

Reputation: 45433

This is due to capture conversion. Internally, compiler converts the type of an expression Foo<?> to Foo<X>, where X is a specific albeit unknown type.

Upvotes: 1

MarianP
MarianP

Reputation: 2759

As an addition to existing (correct) answers to make it more clear:

    ...
        Object result1 = ColTest.wildSub(list, lng); //compiles fine with Sun's javac
//      Long result2 = ColTest.wildSub(list, lng);   //does not compile without explicit casting
        Long result2 = (Long) ColTest.wildSub(list, lng);   //compiles fine 
    ...

Upvotes: 1

newacct
newacct

Reputation: 122439

The compiler is free to infer anything that is compatible with the types of the arguments and return type. In your case it can always infer T as Object. Which turns the signature into

static Object wildSub(ArrayList<?> holder, Object arg)

Which means it can take any ArrayList as first argument and anything as second. Since you don't do anything with the return value, Object will be okay.

Upvotes: 3

xthexder
xthexder

Reputation: 1565

If you think about it as the compiler using Object where ? is used, it makes sense why it would compile. That is all there is to it.

If you are doing any operations dependent on ? being a certain class, you will get a cast exception at run time if the wrong class is passed in.

Upvotes: 2

Related Questions