加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

帮助Java Generics:不能使用“Object”作为参数“? extends Ob

发布时间:2020-12-15 08:37:24 所属栏目:Java 来源:网络整理
导读:我有以下代码: import java.util.*;public class SellTransaction extends Transaction { private MapString,? extends Object origValueMap; public SellTransaction(MapString,? extends Object valueMap) { super(Transaction.Type.Sell); assignValues(
我有以下代码:

import java.util.*;

public class SellTransaction extends Transaction {
    private Map<String,? extends Object> origValueMap;
    public SellTransaction(Map<String,? extends Object> valueMap) {
        super(Transaction.Type.Sell);
        assignValues(valueMap);
        this.origValueMap=valueMap;
    }
    public SellTransaction[] splitTransaction(double splitAtQuantity) {
        Map<String,? extends Object> valueMapPart1=origValueMap;
        valueMapPart1.put(nameMappings[3],(Object)new Double(splitAtQuantity));
        Map<String,? extends Object> valueMapPart2=origValueMap;
        valueMapPart2.put(nameMappings[3],((Double)origValueMap.get(nameMappings[3]))-splitAtQuantity);
        return new SellTransaction[] {new SellTransaction(valueMapPart1),new SellTransaction(valueMapPart2)};
    }
}

当我调用valueMapPart1.put和valueMapPart2.put时,代码无法编译,错误如下:

The method put(String,capture#5-of ? extends Object) in the type Map is not applicable for the arguments (String,Object)

我已经在互联网上阅读了关于泛型和通配符以及捕获的内容,但我仍然不明白出了什么问题.我的理解是Map的值可以是扩展Object的任何类,我认为这可能是多余的,因为所有类都扩展了Object.我无法将泛型更改为类似的东西?超级对象,因为Map是由某些库提供的.

那为什么不编译?此外,如果我尝试将valueMap转换为Map< String,Object>,编译器会向我提供“未经检查的转换”警告.

谢谢!

解决方法

如果库指定扩展,则它们明确禁止放置.你应该在修改之前进行防御性复制,因为他们可以非常合理地将他们的返回类型更改为在新版本中不可变.如果复制很昂贵,那么您可以尝试创建类型为< String,Object>的映射类型.首先查询他们的地图,然后查询您创建的具有本地修改的地图.

如果您确实知道他们的返回类型是不可变的并且您只拥有它,那么@SuppressWarnings(“未经检查”)注释是解决警告的合法方式,但我会仔细检查这些假设并进行广泛评论.

要了解extends vs super,请以这种方式查看.
由于该值可以是扩展Object的任何类型,因此以下内容有效.

Map<String,Number> strToNum = new HashMap<String,Number>();
strToNum.put("one",Integer.valueOf(1));  // OK

Map<String,String> strToStr = new HashMap<String,String>();
strToStr.put("one","1");  // OK

Map<String,? extends Object> strToUnk = randomBoolean() ? strToNum : strToStr;
strToUnk.put("null",null);  // OK.  null is an instance of every reference type.
strToUnk.put("two",Integer.valueOf(2));  // NOT OK.  strToUnk might be a string to string map
strToUnk.put("two","2");  // NOT OK.  strToUnk might be a string to number map

所以put并不适用于扩展边界类型.
但它可以很好地与阅读操作如get:

Object value = strToUnk.get("one");  // We don't know whether value is Integer or String,but it is an object (or null).

如果您希望地图主要使用“put”而不是“get”,那么您可以使用“super”而不是extend,如下所示:

Map<String,Number>();
Map<String,Object> strToObj = new HashMap<String,Object>();

Map<String,? super Number> strToNumBase;
if (randomBoolean()) {
  strToNumBase = strToNum;
} else {
  strToNumBase = strToObj;
}

// OK.  We know that any subclass of Number can be used as values.
strToNumBase.put("two",Double.valueOf(2.0d));

// But now,gets don't work as well.
Number n = strToNumBase.get("one");  // NOT OK.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读