我想知道,除了语法差异之外,何时会在接受泛型参数的方法上使用泛型接口?
public interface Flight<T>{
void fly(T obj);
}
在
public interface Flight{
void <T> fly(T obj);
}
答案 0 :(得分:10)
如果声明通用方法,则始终让调用者决定使用哪种类型参数作为类型参数。该方法的实现必须能够处理所有可能的类型参数(并且它甚至没有办法要求实际的类型参数)。
也就是说,像<T> void fly(T obj);
这样的方法表明调用者可以使用T
的任何类型,而实现可以依赖的唯一内容是T
的实际类型将是可分配给Object
(如果已声明<T extends Object>
)。
所以在这个具体的例子中,它与声明void fly(Object obj);
没有什么不同,它也允许任意对象。
相反, interface
上的类型参数是合同的一部分,可以由{{1}的实现指定或限制}:
interface
允许像
这样的实现public interface Flight<T>{
void fly(T obj);
}
在实施方面修复public class X implements Flight<String> {
public void fly(String obj) {
}
}
的类型。或
T
仍然是通用的,但限制类型。
当public class NumberFlight<N extends Number> implements Flight<N> {
public void fly(N obj) {
}
}
本身是另一种方法签名的一部分时,interface
的签名也很重要,例如
interface
此处,您传递给public void foo(Flight<? super String> f) {
f.fly("some string value");
}
的{{1}}实施必须能够使用Flight
值,因此foo
或String
或{ {1}}已足够,但不是Flight<String>
。声明此类合同需要Flight<CharSequence>
上的类型参数,而不是Flight<Object>
方法。
答案 1 :(得分:0)
当您期望实现中的大多数方法将对实例化类时提供的类型执行操作时,您应该使用泛型类型。
例如,ArrayList<E>
是泛型类型,因为它的大部分操作(添加,获取,删除等)都依赖于创建一个类型时指定的类型。
当类中只有少数方法依赖于不同的类型时,应该使用泛型方法。
您可以在Java Docs中了解有关泛型的更多信息。
答案 2 :(得分:0)
以课程java.util.ArrayList<E>
为例。在创建该类型的变量时,您必须为T
指定具体类型:
ArrayList<String> list = new ArrayList<>();
从List
接口调用方法时,使用这些具体类型,使用类型T
。调用add
方法,您只能将String
个对象添加到列表中。使用get
从列表中检索元素,您将获得具体类型String
的元素。
对于泛型方法,仅为此方法指定类型T
。如果方法返回该泛型类型的值,那将更有意义。您经常会找到这样的代码:
MyObject obj = SomeClass.staticGenericMethod(MyObject.class)
或
MyObject obj = classInstance.genericMethod(MyObject.class);
你应该用大写字母开始你的界面名称:Flight<T>