[英]Accessing a Java generics stored in a Map
I'm trying to access a custom Java generic stored in a map as below. 我正在尝试访问存储在地图中的自定义Java通用,如下所示。
Unfortunately I get a type mis-match error. 不幸的是我得到了类型错误匹配错误。
Now, I can cast it to the type I want because but this seems messy to me. 现在,我可以将它转换为我想要的类型,但这对我来说似乎很混乱。
Is there a clean way of doing the assignment? 有没有干净的工作方式?
Thanks 谢谢
public interface BusinessObject {
}
public class SalesItemA implements BusinessObject {
}
public interface BusinessRuleSuite<T extends BusinessObject> {
public void fire(T shell);
}
public abstract class BusinessRuleSuiteCommon<T extends BusinessObject>
implements BusinessRuleSuite<T> {
public synchronized void fire(T bo) {
// do something with bo;
}
}
public class SalesBusinessRuleSuite extends
BusinessRuleSuiteCommon<SalesItemA> {
}
public class SalesProcessor {
private final Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules;
public SalesProcessor(Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules) {
this.businessRules = businessRules;
}
public void processItem(SalesItemA sia) {
/// This assignment doesn't work??? Why?
BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());
p.fire(sia);
}
}
}
Because the return type of get()
is a BusinessRuleSuite<? extends BusinessObject>
因为
get()
的返回类型是BusinessRuleSuite<? extends BusinessObject>
BusinessRuleSuite<? extends BusinessObject>
. BusinessRuleSuite<? extends BusinessObject>
。
This means it will accept anything that inherits from BusinessObject
during put()
. 这意味着它将接受在
put()
期间从BusinessObject
继承的任何内容。 But when you use it on the right hand side of an assign, Java can't make assumptions. 但是当你在赋值的右侧使用它时,Java无法做出假设。 It has to play safe, so the
get()
behaves as if you had used BusinessRuleSuite<BusinessObject>
(without the extends
). 它必须安全,所以
get()
行为就像你使用了BusinessRuleSuite<BusinessObject>
(没有extends
)。
There are two ways to achieve what you want: 有两种方法可以达到你想要的效果:
Use BusinessRuleSuite<SalesItemA>
in the map declaration 在地图声明中使用
BusinessRuleSuite<SalesItemA>
Use a cast 使用演员
because businessRules is a 因为businessRules是一个
private final Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules
so instead of 而不是
BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());
do 做
BusinessRuleSuite<? extends BusinessObject> p = this.businessRules.get(sia.getClass());
the Map
places no garuantees that for each key ( Class<K>
, BusinessRuleSuite<V>
), K=V
, which i assume is true in your code. Map
没有为每个密钥( Class<K>
, BusinessRuleSuite<V>
), K=V
服务员,我认为你的代码是真的。
public class RuleProcessor<T extends BusinessObject> {
private final Map<Class<T>, BusinessRuleSuite<T>> businessRules;
public SalesProcessor(Map<Class<T>, BusinessRuleSuite<T>> businessRules) {
this.businessRules = businessRules;
}
// - or have a blank constructor, and add them one by one
public void add(Class<T> c, BusinessRuleSuite<T> rs) {
businessRules.add(c, rs);
}
public void processItem(T sia) {
BusinessRuleSuite<T> p = this.businessRules.get(sia.getClass());
p.fire(sia);
}
}
It looks like you are trying to create a single SalesProcessor
class, and change its processItem
method to accept any implementation of BusinessObject
. 看起来您正在尝试创建单个
SalesProcessor
类,并更改其processItem
方法以接受BusinessObject
任何实现。
Neal Gafter tried to make this work by using a "super type tokens" to expand Josh Block's "typesafe heterogenous container" pattern, but it has some flaws . Neal Gafter试图通过使用“超级型代币”来扩展Josh Block的“类型安全的异类容器”模式, 但它有一些缺陷 。
Your map does not contain items of type SalesItemA but of type <? 您的地图不包含SalesItemA类型的项目,但类型为<? extends BusinessObject>
扩展BusinessObject>
change 更改
BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());
to 至
BusinessRuleSuite<BusinessRuleSuite<? extends BusinessObject>> p = this.businessRules.get(sia.getClass());
... not actually tested, so this might not work at all. ......没有经过实际测试,所以这可能根本不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.