有什么区别:
public <T> void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
和
public void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
我读到在返回类型之前使用类型的方法签名应该有<T>
但是为什么我仍然可以在没有<T>
的情况下创建方法?如果我做或不做的话有什么含义?
答案 0 :(得分:25)
在第二种方法中,type参数通常在方法所属的类声明中定义:
class MyClass<T> {
public void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
...
}
所以第二种方法属于泛型类型。 第一种方法是泛型方法,因为它定义了自己的类型参数。
答案 1 :(得分:9)
在第一种情况下,为方法定义了通用参数T
。其他方法可能有不同的T
。
在第二种情况下,为类或接口定义了通用参数T
。该类或接口中的所有方法必须具有相同的T
。
定义类范围的泛型允许您在许多方法上强制使用相同的类型参数。您还可以拥有泛型类型的字段。有关示例,请参阅ArrayList<t>
。
答案 2 :(得分:6)
从第二个例子中,我猜这个方法是在泛型类中定义的:
class SomeClass<T> {
public void createArray(T sample){ ... }
}
第一个和第二个示例之间的区别在于,在第一个示例中,T
实际上是“本地”类型变量。你可以给它一个不同的名字,例如S
,让它更清晰一点:
class SomeClass<T> {
public <S> void createArray(S sample){ ... }
}
因此,S
和T
都是类型变量,但不相关。 T
在类范围内定义,因此可用于在类中的所有方法中引用相同的类型; S
仅在方法范围内定义。
使用名称T
代替S
,您隐藏了类级别类型变量T
。这意味着,例如,以下内容不起作用:
class SomeClass<T> {
public T getWotsit() { ... }
public <T> void createArray(T sample){
T wotsit = getWotsit();
}
}
因为T
签名中的getWotsit
和变量声明T
中的T wotsit
可能会引用不同的类型;如果使用名称S
来编写等效代码,则会更清楚:
class SomeClass<T> {
public T getWotsit() { ... }
public <S> void createArray(S sample){
S wotsit = getWotsit();
}
}
据我所知,如果您定义了一个具有相同名称的方法级类型变量,则无法引用类级别类型变量。
但是,以下两种情况都可以:
class SomeClass<T> {
public T getWotsit() { ... }
// No additional type variable, so T is the class-level type variable.
public void createArray(T sample){
T wotsit = getWotsit();
}
}
class SomeClass<T> {
public T getWotsit() { ... }
// Type variable has different name, so `T` is the class-level
// type variable.
public <S> void createArray(T sample){
T wotsit = getWotsit();
}
}