【发布时间】:2014-02-26 00:44:30
【问题描述】:
这有什么区别:
T getById(Integer id);
还有这个:
<T> T getById(Integer id);
他们不是都返回类型为T 的类吗?
【问题讨论】:
-
第一个是类类型参数,第二个是方法类型参数
这有什么区别:
T getById(Integer id);
还有这个:
<T> T getById(Integer id);
他们不是都返回类型为T 的类吗?
【问题讨论】:
在第一个 sn-p 中,T 指的是在类的类型参数列表中声明的类型变量。
在第二个 sn-p 中,您正在创建一个新的类型变量 T(它可能会影响类一),在方法参数列表中声明。
【讨论】:
是的,但您必须在某处声明T。改变的是你在哪里做的。
T 是在类级别定义的,因此您的方法是泛型类的一部分,您必须在声明/实例化时专门化该类。 T 对于类中的所有方法和属性都是相同的。T 是在方法级别定义的,所以它是一个泛型方法。 T 的值(通常)可以推断出来。第一种情况T的范围是整个类,而第二种情况只是方法。
第二种形式通常与静态方法一起使用。另外,后者的优点是可以推导出类型变量T(大多数情况下不必指定),而前者必须指定。
具体来说,如果泛型类的某些属性依赖于T(类型为T、List<T> 等),则必须使用泛型类。
【讨论】:
第一个返回封闭泛型类型的类型 T。例如,
T get(int index);
在List<T> 类中声明,在List<T> 的给定索引处返回类型 T 的元素。
第二个声明方法本身是一个泛型方法,它的返回类型取决于它被调用的方式。如果您将其调用为
String s = theObject.<String>getById(id);
它将返回一个字符串。如果你调用它
Foo f = theObject.<Foo>getById(id);
它将返回一个 Foo。大多数时候,泛型类型是由编译器自动推断出来的,所以你可以简单地写
Foo f = theObject.getById(id);
具体例子见
static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
返回 T 集合中 T 类型的最大元素。方法返回的类型取决于传递给方法的集合的类型。
【讨论】:
其他答案在使用时解释得很好,我提供了一个例子
对于第 1 点
class ArrayList<E> {//implementing and extending
public E get(int index) {
}
}
对于第 2 点:静态实用方法
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}
【讨论】: