Java 泛型接口的非泛型子类

Java 泛型接口的非泛型子类,java,generics,Java,Generics,我有一些通用接口 interface Animal<T> {} 似乎由于源代码的类型是String,而pet的类型是pet,它实现了Animal,所以这里应该有一个类型不匹配并导致编译器错误,但我发现这是编译的,我想知道是否有人能解释原因。String也是一个对象(所有非原语也都是对象)。因此,这里的apply方法工作得很好,将T绑定到object,在这一点上,所有东西都对齐了。这就像有一个方法:foo(object x),并将其称为foo(“”),这非常好。您正在使用绑定泛型 c

我有一些通用接口

interface Animal<T> {}
似乎由于源代码的类型是
String
,而pet的类型是
pet
,它实现了
Animal
,所以这里应该有一个类型不匹配并导致编译器错误,但我发现这是编译的,我想知道是否有人能解释原因。

String也是一个对象(所有非原语也都是对象)。因此,这里的apply方法工作得很好,将T绑定到object,在这一点上,所有东西都对齐了。这就像有一个方法:
foo(object x)
,并将其称为
foo(“”
),这非常好。

您正在使用绑定泛型

class Pet implements Animal<Object>
宠物类动物

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

因为您调用的方法
apply
没有明确指定类型e在尖括号之间,您依赖编译器为您推断一个。如果您尝试将结果分配给某种类型的变量,例如
String
,编译器将告诉您它推断的类型,例如:

String r = Animal.apply(source, pet);
类型不匹配:无法从对象转换为字符串

在这种情况下,您知道
T
被推断为
Object
。如果您传递两个
String
实例,
T
将被推断为
String

String r = Animal.apply("A", "B");
请注意,Java允许您显式指定泛型方法(称为type witness)的类型参数。这有助于检查您对如何绑定类型参数的假设:

Animal.<Object>apply(source, pet);
Animal.apply(来源,宠物);

更多信息:

因为<代码>字符串是<代码>对象!?源参数只是T而不是动物。没有任何东西说源和目标必须相同仅供参考,这称为“绑定”,而不是“铸造”,至少,如果我们遵循Java语言规范中使用的说法。只是吹毛求疵:)你是对的。我后来在帖子里看到了,但一开始就错过了。
String r = Animal.apply(source, pet);
String r = Animal.apply("A", "B");
Animal.<Object>apply(source, pet);