[英]“Attempting to use incompatible return type” with class implementing Serializable
我有以下界面:
切片机
public interface Slicer {
Optional<Map<String, ? extends Serializable>> pointer();
}
我有一个实现:
DynamoDbSlicer
public abstract class DynamoDbSlicer implements Slicer {
@Override
public abstract Optional<Map<String, AttributeValue> pointer();
}
其中, AttributeValue
来自AWS开发工具包,定义为:
public final class AttributeValue implements SdkPojo, Serializable, ToCopyableBuilder<AttributeValue.Builder, AttributeValue> {
注意,它实现了Serializable
。
我在DynamoDbSlicer
的抽象方法上遇到编译器错误:
pointer() in DynamoDbSlicer clashes with pointer() in Slicer; attempting to use incompatible return type
我想念什么?
乍一看,这似乎应该编译,因为Java(从1.5开始)具有返回类型协方差。 这意味着重写方法可以声明一个返回类型,该类型是原始方法返回类型的子类型。
看起来Optional<Map<String, Serializable>>
是Optional<Map<String, ? extends Serializable>>
Optional<Map<String, ? extends Serializable>>
,但不是。 有趣的是,如果您从两种返回类型中都删除了Optional
部分,则会进行编译。
interface Slicer {
Map<String, ? extends Serializable> pointer();
}
abstract class DynamoDbSlicer implements Slicer {
@Override
public abstract Map<String, Serializable> pointer();
}
之所以进行编译,是因为Map<String, Serializable>
是Map<String, Serializable>
的子类型Map<String, ? extends Serializable>
Map<String, ? extends Serializable>
-可以将前者的实例分配给后者类型的变量。
但是,添加Optional
会使它由于List<Dog>
不是List<Animal>
原因而无法编译-泛型是不变的。 在这个类比中, Dog
类似于与Map<String, Serializable>
匹配的特定子类型,而Animal
类似于与Map<String, ? extends Serializable>
Map<String, ? extends Serializable>
。 就像List<Dog>
不是List<Animal>
, Optional<Map<String, Serializable>>
不是Optional<Map<String, ? extends Serializable>>
Optional<Map<String, ? extends Serializable>>
。
在不删除Optional
位的情况下进行编译的最简单方法是完全匹配类型。
abstract class DynamoDbSlicer implements Slicer {
@Override
public abstract Map<String, ? extends Serializable> pointer();
}
如果这不符合您的要求,则需要在您的类可以作为类型实参提供的接口上创建一个类型实参。
interface Slicer<T extends Serializable> {
Optional<Map<String, T>> pointer();
}
abstract class DynamoDbSlicer implements Slicer<AttributeValue> {
@Override
public abstract Optional<Map<String, AttributeValue>> pointer();
}
使用type参数可以对其进行编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.