Java通用接口与通用方法,以及何时使用一个

时间:2015-06-01 13:55:24

标签: java generics methods interface parameterized

我想知道,除了语法差异之外,何时会在接受泛型参数的方法上使用泛型接口?

public interface Flight<T>{
   void fly(T obj);
}

public interface Flight{
    void <T> fly(T obj);
}

3 个答案:

答案 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值,因此fooString或{ {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>