Java 声纳抱怨静态分配

Java 声纳抱怨静态分配,java,sonarqube,Java,Sonarqube,我将此赋值给从文件中读取数据的静态变量: public static final Map<String, Integer> MY_DATA_RESOURCE; static { MY_DATA_RESOURCE = parseAndTransformFile(); } 公共静态最终地图MY_数据_资源; 静止的{ MY_DATA_RESOURCE=parseAndTransformFile(); } 我希望所有类都可以公开访问此变量,并希望使用此方法调用对其进行初始化

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

public static final Map<String, Integer> MY_DATA_RESOURCE;
static {
    MY_DATA_RESOURCE = parseAndTransformFile();
  }
公共静态最终地图MY_数据_资源;
静止的{
MY_DATA_RESOURCE=parseAndTransformFile();
}
我希望所有类都可以公开访问此变量,并希望使用此方法调用对其进行初始化。这样做会引发声纳抱怨“可变场不应该是“公共静态的”

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


我这里还有其他选项吗?

但是你的字段被声明为
final
,映射本身并不是不可变的,你仍然可以
把一些项目放到它上面(除非你使用的是一些
集合。不可修改的映射()
-但无论如何你不知道这个接口),这就是为什么Sonar抱怨的原因

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

公共静态最终不可变映射我的数据\u资源=
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);
}
私有静态最终映射MY_数据_资源;
静止的{
MY_DATA_RESOURCE=parseAndTransformFile();
}
公共静态映射myDataResource(){
返回集合。不可修改映射(我的数据资源);
}

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

尝试删除final并查看声纳违规情况。该final存在是因为声纳投诉
public static final Map MY\u DATA\u RESOURCE=Collections.unmodifiableMap(parseAndTransformFile())
?我喜欢这个想法。没有业务逻辑重字段的默认类型听起来是更好的做法,尽管这有让访问更详细的缺点,但我刚刚意识到“详细”是什么意思?如果我将映射隐藏在POJO中,我还需要额外的步骤来从中获取项目。使用Collections.unModifiableMap尽管我喜欢,但仍然有效然而,使用静态方法的想法似乎是每次重新创建
unmodifalemap
实例都会增加开销-我建议公开一些
getValueByKey
方法,该方法将公开
Map.get()
unmodifiableMap创建起来很便宜——它实际上不会复制内容。相反,您可以使用不可修改的Map,而不用担心不可修改的内容
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);
}