vs <t> </t>

时间:2009-03-29 16:30:16

标签: java generics

我偶然发现了一个看起来像这样的函数:

public void function(Class<?> clazz) {...}

将方法更改为:

的优点/缺点是什么?
public <T> void function(Class<T> clazz) {...}

编辑:什么是编译时/运行时差异。

4 个答案:

答案 0 :(得分:10)

使用“?”与“任何”相同,而“T”表示“特定类型”。所以,比较这些接口:

public interface StrictClass<T> {
 public T doFunction(Class<T> class);
}

public interface EasyClass<T> {
 public > doFunction(Class<?> class);
}

现在,我们可以创建类:

public class MyStrictClass implements StrictClass<String> {
  public String doFunction(Class<String> stringClass) {
    //do something here that returns String
  }
}

public class MyEasyClass implements EasyClass<String> {
  public String doFunction(Class<?> anyClass) {
    //do something here that returns String
  }
}

希望有所帮助!

答案 1 :(得分:7)

todd.run完全正确,但这只是答案的一半。当您不将类型参数添加到包含该方法的类时,还有用于选择<T>而不是<?>(或反之亦然)的用例。例如,考虑

之间的区别
public <E extends JLabel> boolean add(List<E> j) {
    boolean t = true;
    for (JLabel b : j) {
        if (b instanceof JLabel) {
            t = t && labels.add(b);
        }
    }
    return t;
}

public boolean add(List<? extends JLabel> j) {
    boolean t = true;
    for (JLabel b : j) {
        if (b instanceof JLabel) {
            t = t && labels.add(b);
        }
    }
    return t;
}

第一种方法实际上不会编译,除非您向封闭类添加适当的类型参数,而第二种方法将编译,无论封闭类是否具有类型参数。如果您不使用<?>,那么您在本地负责告诉编译器如何获取将由其所在位置使用的字母填写的类型。你经常遇到这个问题 - 需要使用吗?而不是T - 当试图编写使用或需要“扩展”和“超级”的泛型方法时。 Gilad Bracha's Generics Tutorial (PDF)的第18页对此问题进行了更好但更精细的处理。另请参阅this stack overflow question,其答案阐明了这些问题。

查看此堆栈溢出链接,了解有关第二个问题的信息:Java generics - type erasure - when and what happens。虽然我不知道关于<?><T>之间编译时差的问题的答案,但我很确定答案可以在this FAQ找到,而erickson在那里提到交。

答案 2 :(得分:2)

基本上,它们是等价的。您可以使用第一种语法,您不需要声明类型为T的任何内容。

更新:哦,T可以用来将类型绑定在一起:如果在函数的不同部分使用Class<T>,它将引用同一个类,但不引用Class<?>

答案 3 :(得分:0)

一个好资源可能就是这样:http://sites.google.com/site/io/effective-java-reloaded 与你的问题相关的有趣部分从第5分钟开始。 只是沉溺于之前的用户说的话。

希望有所帮助:]