实战案例丨代码优化:如何去除context中的warning?

举报
技术火炬手 发表于 2020/07/09 10:37:49 2020/07/09
【摘要】 如何去除context中的warning?这篇文章可以告诉你

在一个java语言群里面,有人抛了这么一段代码出来,问题是出现了下下图中的warning,问有什么好的方法消除

image.png

image.png

这种强转都是因为类型链条断掉了,写入的时候擦除了类型,读出来的时候也就只能强转了,那个instanceof 其实并没有帮到什么忙,无外乎把A异常变成了B异常。

最简单的解决方法也非常直观,就是加上 @SuppressWarnings("unchecked")。

这里先不谈用其他的方法相对优雅的除掉这个warning,而是看看这段代码本身的问题。

这是一个context,这种模式就是一个数据容器,啥都能装,通过编码的人来保证类型匹配,进去擦除类型,出来补上类型,能不能弄对,全看人。

这种模式类似于在其他的语言里面就拿个容器类型就开始编程,忽略一切的type信息。

我们应当能够看到几个问题

1. context装进去的是有类型化的对象,出来就没有了,设计上讲究封装性,封装基本的就要保证对称,那么context抹除掉的东西,就应该由他来补上。

2. 由于他没有补上,所以所有使用的地方自己来补充,代码其实会产生很多冗余,考虑到他是一个context,那么实际上其他地方一定还有很多处有类似的代码

3. 这里模拟的其实是一个computeIfAbsent的逻辑,如果没有对象就补一个默认值,然后set进去,借用了isEmpty来婉转的表达容器里面没有这个元素。这里作者应当对java容器上的computeIfAbsent一类的方法不熟悉,因为兜兜转转做的就是这个事情。

4. 由于没有用computeIfAbsent,自己的实现中,无论对象是否存在于context中,都会new一个HashMap出来,这在多数情况下,都是一个浪费。

5. 更不要说,当他发现类型不匹配的时候,仅仅打了一行日志。 元素没有推进去,程序也不知道,只有日志知道了。

下面是一个建议的解决方案

1.  context做对称设计,出来的时候就把类型转换好,不要让调用者自己来做。 这样抑制告警就在一处即可。

2.  实现computeIfAbsent的逻辑封装,有就返回,没有就插入一个对象,然后返回对象。 对象的创建是按需的。

context的包装类样子如下

public static class SomeClass {
    Map<String, Object> context = new HashMap<>();

    @SuppressWarnings("unchecked")
    public <T> T computeIfAbsent(String key, Supplier<T> defaultGen) {
        return (T) context.computeIfAbsent(key, k -> defaultGen.get());
    }
}

使用者样子如下

public static class Usage {
    public void test() {
        SomeClass workingClass = new SomeClass();
        Supplier<Integer> wantToAppendItem = () -> 2;

        Map<String, Supplier<Integer>> element = workingClass.computeIfAbsent("my-key", HashMap::new);
        element.put("level2-key", wantToAppendItem);

        Supplier<String> wantToAppendStringItem = () -> "good";
        workingClass.computeIfAbsent("my-str-key", HashMap::new).put("level2-str-key", wantToAppendStringItem);
    }
}

是不是会好一点,业务也更聚焦一点,从鸡毛蒜皮的重复中解脱出来了?



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。