我经常在Java中找到使用泛型的代码:
public static <T extends Object & Interface> foo(T object) {
...
}
因为在Java中,每个类都继承自对象类,所以我不确定extends Object
是否具有特殊含义或用于特殊目的。任何人都可以告诉我,如果有不同的背景使用这个或者这是隐含的,当你采取<T extends Interface>
?
答案 0 :(得分:5)
<T extends Object & Interface>
Object
显然是多余的,通常等于
<T extends Interface>
请注意,强烈建议不要使用Interface
作为班级名称。
答案 1 :(得分:0)
正如您所指出的,任何T
都会隐式地延伸Object
。明确定义T extends Object
是完全多余的,您可以(也可能应该)将其删除,只需定义T extends Interface
。
答案 2 :(得分:0)
此可能是使您的代码在二进制级别向后兼容所必需的。假设您有以下实用程序类:
public class Utils {
public static <T> int length(T obj) {
if(obj instanceof CharSequence) {
return ((CharSequence)obj).length();
}
return 0;
}
}
它作为库发布,并在某些应用程序中使用:
public class Main {
public static void main(String... args) {
System.out.println(Utils.length("foo"));
}
}
工作正常。但是后来你决定将方法仅限于某些接口CharSequence
的实现是好的,因为对于其他对象,它总是返回0并且似乎没有人使用你的方法和非CharSequence参数。所以你将签名改为
public static <T extends CharSequence> int length(T obj) { ... }
现在,如果您将Main
课程与图书馆的新版本相关联,则会因java.lang.NoSuchMethodError
而失败。那是因为你方法的擦除签名发生了变化。在int length(Object obj)
之前,但现在是int length(CharSequence obj)
。如果重新编译Main
类,它将正常工作,但并不总是可以重新编译所有现有代码。因此可以执行诀窍:
public static <T extends Object & CharSequence> int length(T obj) { ... }
现在你实际上是将参数限制为CharSequence
界面,但删除的签名又回到int length(Object obj)
(删除的类型始终是A & B & C & ...
链中的第一个,它是正式记录),因此新版本的Utils
类与旧代码二进制兼容。