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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.