繁体   English   中英

访问存储在Map中的Java泛型

[英]Accessing a Java generics stored in a Map

我正在尝试访问存储在地图中的自定义Java通用,如下所示。
不幸的是我得到了类型错误匹配错误。
现在,我可以将它转换为我想要的类型,但这对我来说似乎很混乱。
有没有干净的工作方式?
谢谢

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

因为get()的返回类型是BusinessRuleSuite<? extends BusinessObject> BusinessRuleSuite<? extends BusinessObject>

这意味着它将接受在put()期间从BusinessObject继承的任何内容。 但是当你在赋值的右侧使用它时,Java无法做出假设。 它必须安全,所以get()行为就像你使用了BusinessRuleSuite<BusinessObject> (没有extends )。

有两种方法可以达到你想要的效果:

  1. 在地图声明中使用BusinessRuleSuite<SalesItemA>

  2. 使用演员

因为businessRules是一个

private final Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules

而不是

BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());

BusinessRuleSuite<? extends BusinessObject> p = this.businessRules.get(sia.getClass());

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

看起来您正在尝试创建单个SalesProcessor类,并更改其processItem方法以接受BusinessObject任何实现。

Neal Gafter试图通过使用“超级型代币”来扩展Josh Block的“类型安全的异类容器”模式, 但它有一些缺陷

您的地图不包含SalesItemA类型的项目,但类型为<? 扩展BusinessObject>

更改

BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());

BusinessRuleSuite<BusinessRuleSuite<? extends BusinessObject>> p = this.businessRules.get(sia.getClass());

......没有经过实际测试,所以这可能根本不起作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM