2

Consider this code:

public <T> List<T> meth(List<?> type) { System.out.println(type); // 1 return new ArrayList<String>(); // 2 } 

It does not compile at line 2, saying that List is required.

Now, if it's changed to:

public <T> List<?> meth(List<T> type) { System.out.println(type); // 1 return new ArrayList<String>(); // 2 } 

It does compile. Why? I thought the difference between declaring a generic type with T and using the wildcard was that, when using the wildcard, one cannot add new elements to a collection. Why would <?> allow a subtype of List to be returned? I'm missing something here, what's the explicit rule and how it's being applied?

2
  • What is your original goal? What do you want to accomplish with your method? Commented Jul 19, 2009 at 14:09
  • Nothing really, this isn't part of a project, I just wanna understand java generic methods. I' reading this right now java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf Commented Jul 19, 2009 at 14:11

3 Answers 3

4

The difference is in the return type declaration. List<String> is not a subtype of List<T>, but it is a subtype of List<?>.

List<?> makes no assumptions regarding its type variable, so the following statements are valid:

List<?> l0 = new ArrayList<String>(); List<?> l1 = new ArrayList<Object>(); List<? extends Number> ltemp = null; List<?> l2 = ltemp; 

List<T> assumes that the type argument will be resolved in the context of client (e.g. type use), when you declared it as List<String> or List<Object>. Within the method body, you cannot make any assumptions about it either.

Sign up to request clarification or add additional context in comments.

1 Comment

I don't think the last compiles.
1

In the first case, T is not necessarily a superclass of String. If you choose a T like Integer and call the method, it'll fail; so it won't compile. However, the second will compile as surely, any ArrayList<String> is a valid List of something.

Comments

1

As said earlier, String isn't a subtype of T, so it's why it does not work. However, this code works :

public <T> List<T> meth(List<?> type) { System.out.println(type); // 1 return new ArrayList<T>(); // 2 } 

and is more in the idea of what you want, I think.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.