[英]Java Generic Return type Issue
我在下面的Java代码中收到一个非常奇怪的编译错误。
我有一个简单的接口,具有具有通用返回类型的API:
public interface AttributeGenerator {
<T> T generateAttribute(Record record);
}
我可以写一个实现,这个可以编译:
public class StringAttributeGenerator implements AttributeGenerator {
@Override
public String generateAttribute(Record record) {
return "Test";
}
}
现在,可以说,我在上面的界面中添加了另一个参数。
public interface AttributeGenerator {
<T> T generateAttribute(Record record, Set<Integer> indices);
}
我提供了另一种实现方式:
public class StringAttributeGenerator implements AttributeGenerator {
@Override
public String generateAttribute(Record record, Set<Integer> indices) {
return "Test";
}
}
编译失败,编译器抱怨:
该方法不会从其超类重写。
我不明白为什么编译器不能编译第二个实例,如果不是,我想理解为什么Java无法为用户提供编写此类代码的便利。
AFAIK问题在于,在第一种情况下,您实际上是在禁用泛型。 在这种情况下,这将导致T
被强制转换为Object
,并且由于返回类型为协方差,因此返回String
是可以的。 但是,这应该会产生警告,因为您基本上是在迫使编译器忽略泛型并使用“传统”方式,这相当于直接编写Object generateAttribute( Record record )
。
在第二种情况下,如果以上述方法禁用泛型,则签名将看起来像generateAttribute(Record record, Set indices)
,其中第二个参数等效于Set<Object>
,因此签名不再匹配。
还要注意,虽然您的第一个代码段可以编译,但是您可能会遇到运行时问题,例如,如果您执行了以下操作:
AttributeGenerator unknownGenerator = new StringAttributeGenerator();
//You'd get a string and the system would try to cast to Integer, which clearly will fail
Integer iWontCompile = unknownGenerator.generateAttribute( someRecord );
您可以在接口中定义T
,例如:
public interface AttributeGenerator<T> {
T generateAttribute(Record record, Set<Integer> indices);
}
public class StringAttributeGenerator implements AttributeGenerator<String> {
@Override
public String generateAttribute(Record record, Set<Integer> indices) {
return "Test";
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.