通用接口的非通用子类

时间:2019-11-26 18:00:00

标签: java generics

我有一些通用接口

interface Animal<T> {}

我有一个只想扩展Animal<Object>的子类。所以我做到了

class Pet implements Animal<Object>

我有一些方法只能在两个参数都具有匹配类型的情况下编译:

<T> T apply(T source, Animal<T> target)

我想知道为什么会编译

String source = "test";
Pet pet = new Pet();
apply(source, pet);

看来,由于源类型为String,宠物类型为Pet,它实现了Animal<Object>,因此此处应该存在类型不匹配并导致编译器错误,但是我发现它可以编译,并且想知道是否有人可以解释原因。

3 个答案:

答案 0 :(得分:1)

由于您在调用方法div时未在尖括号之间明确指定类型,因此您依赖编译器为您推断一个。如果您尝试将结果分配给某个类型的变量,例如apply,则编译器会告诉您它推断的类型,例如:

String
  

类型不匹配:无法从对象转换为字符串

在这种情况下,您知道String r = Animal.apply(source, pet); 被推断为T。如果您传递两个Object实例,则将String推断为T

String

请注意,Java允许您为通用方法(称为 type见证人)显式指定type参数。这对于检查关于类型参数如何绑定的假设很有用:

String r = Animal.apply("A", "B");

更多信息:Java Tutorial

答案 1 :(得分:0)

字符串也是一个对象(所有非原语也是对象)。因此,这里的apply方法可以正常工作,并将T绑定到对象,此时所有内容都对齐。就像有一个方法:foo(Object x),然后将其称为foo("")一样。

答案 2 :(得分:0)

您正在铸造绑定通用

class Pet implements Animal<Object>

到对象类。 Java中的所有内容都是对象类的后代,因此编译器在此不会有任何问题。当您声明您的类实现了Animal时,您需要将其绑定到特定的类型,以限制它对参数的接受。