[英]Fixing error in java: incompatible types: java.lang.Object cannot be converted to capture#1 of?
[英]Type safe merging of Map with multiple types for its value; `incompatible types java.lang.Object cannot be converted to capture#1 of ?`
我有一个容器类,它有一个Map
,它携带多种类型的值。 为了从外部的角度来看是类型安全的,键本身有一个泛型类型,指示值的类型。
键提供了一些基本的工具来查找项目并合并它们的值。 (找到的值类型可能有不同的合并规则)。
public abstract class Key<T> {
@SuppressWarnings("unchecked")
T get(Map<Key<?>, Object> data) {
return (T) data.get(this);
}
/**
* This must be provided by the implementation.
*
* @param old the old value
* @param new the new value
* @returns the merged value
*/
abstract T merge(T old, T new);
}
Container
类看起来像这样。
public class Container {
private final Map<Key<?>, Object> data = new HashMap<>();
public <T> Optional<T> get(Key<T> key) {
return Optional.ofNullable(key.get(data));
}
public <T> Container set(Key<T> key, T value) {
data.put(key, value);
return this;
}
@SuppressWarnings("unchecked")
public <T> Container merge(Key<T> key, T newValue) {
data.compute(key, (k, oldValue) -> key.merge((T) oldValue, newValue));
return this;
}
public Container mergeAll(Container that) {
//this does not compile: incompatible types java.lang.Object cannot be converted to capture#1 of ?
that.data.forEach((key, value) -> this.data.merge(key, value, key::merge));
return this;
}
}
除了最后一个mergeAll
方法之外,所有这些都可以正常工作。 它正在查看that
容器的所有键并将它们的值与this
容器的值合并。
但是, key::merge
无法编译并出现错误incompatible types java.lang.Object cannot be converted to capture#1 of ?
.
在单个merge()
方法中,我通过将类型转换为(T)
来解决它。 但在这种情况下,我没有泛型类型,它是?
,但我不能做这样的事情: (key, oldValue) -> key.merge((?) oldValue, (?) value)
因为你不能转换为(?)
。
有没有解决的办法? 或者更好的模式来实现我想要实现的目标?
您应该能够通过编写以下内容来解决此问题:
public Container mergeAll(Container that) {
that.data.forEach((key, value) -> this.data.merge(key, value, ((Key<Object>) key)::merge));
return this;
}
在您的示例中, key
具有无界通配符类型Key<?>
,因此接受泛型参数的方法只能接受null
。 由于传递给merge
的值属于Object
类型,因此您可以将key
为Key<Object>
。
如果这适用于您的情况,另一种解决方案可能是将Key<?>
更改为Key<Object>
。
我认为它不会比这更安全,因为映射Map<Key<?>, Object> data
没有提示编译器该值的类实际上应该是钥匙。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.