【问题标题】:Sonar complaining about static assignment声纳抱怨静态分配
【发布时间】:2019-08-08 05:00:32
【问题描述】:

我将这个赋值给一个从文件中读取数据的静态变量:

public static final Map<String, Integer> MY_DATA_RESOURCE;
static {
    MY_DATA_RESOURCE = parseAndTransformFile();
  }

我希望所有类都可以公开访问这个变量,并且我想用这个方法调用来初始化它。这样做会触发 Sonar 投诉“但可变字段不应该是“公共静态的”。

我有那个 parseAndTransform 方法,我不想直接多次调用它并且每次都触发读取,我还想避免添加一个 getter 方法,它基本上是为数据访问添加第三层。

我还有其他选择吗?

【问题讨论】:

  • 尝试删除 final 并查看声纳违规。
  • 决赛是因为声纳投诉
  • public static final Map&lt;String, Integer&gt; MY_DATA_RESOURCE = Collections.unmodifiableMap(parseAndTransformFile());?

标签: java sonarqube


【解决方案1】:

但是你的字段被声明为final,映射本身不是不可变的,你仍然可以put() 一些项目到它(除非你使用一些Collections.unmodifiableMap() - 但无论如何你不知道这个接口)这就是Sonar抱怨的原因

尝试将Map包装在一些不可变的类实现中,并将字段的类型更改为此类。这有这个额外的优势,如果将来您决定需要添加一些关于文件的额外元数据(如创建时间)而不是在Map 结构中雕刻,您可以轻松地将字段添加到您自己的映射器类

【讨论】:

  • 我喜欢这个主意。没有业务逻辑重字段的默认类型听起来也是更好的做法
  • 虽然我刚刚意识到这有使访问更加冗长的缺点
  • “冗长”是什么意思?
  • 如果我将地图隐藏在 POJO 中,我还需要额外的步骤来从中获取项目。虽然使用 Collections.unModifiableMap 有效
【解决方案2】:

你可以使用 Guava 的immutable maps:

public static final ImmutableMap<String, Integer> MY_DATA_RESOURCE = 
    ImmutableMap.copyOf(yourMethodCall());

你也可以使用静态方法,而不是字段:

private static final Map<String, Integer> MY_DATA_RESOURCE;

static {
  MY_DATA_RESOURCE = parseAndTransformFile();
}

public static Map<String, Integer> myDataResource() {
  return Collections.unmodifiableMap(MY_DATA_RESOURCE);
}

使用这种方法,您最终还可以决定懒惰地解析和转换文件(当有人询问其内容时),而不是在 static {} 块中。

【讨论】:

  • 我喜欢使用静态方法的想法,但是似乎每次重新创建 unmodifableMap 实例都是开销 - 我建议公开一些 getValueByKey 方法,该方法会公开 Map.get()
  • unmodifiableMap 创建起来很便宜——它实际上并没有复制内容。相反,您可以使用 ImmutableMap 而不必担心不可修改
猜你喜欢
  • 2015-12-22
  • 2017-01-13
  • 1970-01-01
  • 2016-12-17
  • 1970-01-01
  • 2022-01-12
  • 2019-02-06
  • 2015-03-23
相关资源
最近更新 更多