Java通用方法问题

时间:2009-07-19 14:04:50

标签: java generics

考虑以下代码:

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

它不在第2行编译,说List是必需的。

现在,如果它改为:

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

它确实编译。为什么?我认为使用通配符声明泛型类型和使用通配符之间的区别在于,当使用通配符时,无法向集合中添加新元素。为什么<?>允许返回List的子类型?我在这里遗漏了一些东西,明确规则是什么以及它是如何应用的?

3 个答案:

答案 0 :(得分:4)

区别在于返回类型声明。 List<String>不是List<T>的子类型,但它是List<?>的子类型。

List<?>不对其类型变量做出任何假设,因此以下语句有效:

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

List<T>假设当您将其声明为List<String>List<Object>时,将在客户端(例如,类型使用)的上下文中解析type参数。在方法体内,你也不能对它做任何假设。

答案 1 :(得分:1)

在第一种情况下,T不一定是String的超类。如果您选择T之类的Integer并调用该方法,则会失败;所以它不会编译。但是,第二个肯定会编译,任何ArrayList<String>都是某事的有效List

答案 2 :(得分:1)

如前所述,String不是T的子类型,因此它不起作用。但是,此代码有效:

public <T> List<T> meth(List<?> type)
{
   System.out.println(type); // 1
   return new ArrayList<T>(); // 2
}
我认为,更多的是想要你想要的东西。