1. 问题引出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class QuotaInfoView { private Map extra; public void addExtraMap (String key, Object value) { if (extra == null ) { extra = new HashMap <>(16 ); } extra.put(key, value); } public void addExtraMap (Map map) { if (MapUtils.isEmpty(map)) { return ; } if (extra == null ) { extra = Maps.newHashMapWithExpectedSize(map.size()); } extra.putAll(map); } }
如果客户端想要使用如下方式调用的话,则会编译失败
1 2 3 4 5 public void test () { Map map = new HashMap <>(); quotaInfoView.addExtraMap(map); }
2. 巧用泛型通配符解决 那么对于以上的问题我们怎么解决呢?可以使用三种泛型方式来解决
尝试一 只要是String及其父类都可以放进来
1 2 3 4 5 6 7 8 9 10 11 public void addExtraMap (Map map) { if (MapUtils.isEmpty(map)) { return ; } if (extra == null ) { extra = Maps.newHashMapWithExpectedSize(map.size()); } extra.putAll(map); }
但是对于这种形式,如果我使用如下的写法,仍然会编译失败
1 2 3 4 5 public void test () { Map map = new HashMap <>(); quotaInfoView.addExtraMap(map); }
尝试二 我们看一下String和Integer的通用父类是谁,那一定是object了
1 2 3 4 5 6 7 8 9 10 11 public void addExtraMap (Map map) { if (MapUtils.isEmpty(map)) { return ; } if (extra == null ) { extra = Maps.newHashMapWithExpectedSize(map.size()); } extra.putAll(map); }
这种方式还可以再简化
1 2 3 4 5 6 7 8 9 10 11 public void addExtraMap (Map map) { if (MapUtils.isEmpty(map)) { return ; } if (extra == null ) { extra = Maps.newHashMapWithExpectedSize(map.size()); } extra.putAll(map); }
推荐阅读 [EffectiveJava]读书笔记
3. 扩展字段的推荐写法 大家都特别喜欢用扩展字段,但是开发没有银弹,扩展字段用时一时爽,维护火葬场,如下所示:有两个问题,一个是类型强转抛出NPE等,一个是不知道扩展字段里面究竟放的什么
1 2 3 4 5 public void test () { long a = (long )model.getExt("a" ); }
那么怎么才能在使用扩展字段的同时,也降低我们的维护成本呢?笔者推荐一种处理方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class ExtendInfoKey { private final String key; private final Class clazz; public ExtendInfoKey (String key, Class clazz) { this .key = key; this .clazz = clazz; } public String getKey () { return key; } public Class getClazz () { return clazz; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class ExtendInfoUtils { public static T getExtendValue (ExtendInfoKey key, Map attrs) { if (MapUtils.isEmpty(attrs)) { return null ; } String value = attrs.get(key.getKey()); return JSON.parseObject(value, key.getClazz()); } public static void addExtendInfo (ExtendInfoKey key, T value, Map attrs) { if (Objects.isNull(attrs)) { throw new NullPointerException ("attrs can not be null" ); } if (value != null ) { attrs.put(key.getKey(), JSON.toJSONString(value)); } } }