Java 通用返回类型问题

标签 java generics jvm

我在下面的 Java 代码中遇到了一个非常奇怪的编译错误。

我有一个简单的接口(interface),它有一个具有通用返回类型的 API:

public interface AttributeGenerator {

    <T> T generateAttribute(Record record);
}

我可以编写一个实现,并且这个可以很好地编译:

public class StringAttributeGenerator implements AttributeGenerator {

     @Override
     public String generateAttribute(Record record) {
          return "Test";
     }
}

现在,假设我向上述接口(interface)添加另一个参数。

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";
     }

}

编译失败并且编译器提示:

该方法不会从其父类(super class)重写。

我无法理解为什么编译器无法编译第二个实例,如果不能,我想理解为什么Java不能为用户提供编写此类代码的工具。

最佳答案

据我所知,问题在于,在第一种情况下,您实际上禁用了泛型。这将导致 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";
  }
}

关于Java 通用返回类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33524714/

相关文章:

c# - 为什么接受引用类型的泛型方法不接受可空类型作为参数?

java - Hotspot JVM 如何处理 x86 上的整数除法溢出?

java - Glide 未从 firebase 加载图像

java - Java 中的位运算 : Test if in "1010101111011" a bit is set?

c# - 这是对泛型的滥用吗?

Java进程在发送kill信号时不会终止

java - 为什么 JVM 程序在较小的堆大小设置下运行得更快?

java - java中的回文,要求用户输入不同的输入,直到他们输入stop,该方法应该删除所有空格并使字母小写

java - 在单个客户端上执行两个 HTTPS POST 调用 - Java 到 Vb.Net

java - 无法从 java.lang.Class<T> 转换为 java.lang.Class<T>