在使用public static
变量时,我遇到了SonarQube的问题,问题是SonarQube希望将其设为public static final
,此变量正在代码的其他部分填充,它是“动态”(填充环境变量),然后在所有其他类中使用。
这是arrayList变量
public static List<String> listPersons = new ArrayList<>();
Sonar的错误:
1- Make this "public static listPersons" field final
2- Make listPersons a static final constant or non-public and provide accessors if needed
3- Make this member "protected"
解决此问题的最佳方法是什么?
答案 0 :(得分:1)
最好的方法不是创建public static
,而是创建final
字段。因为这可能导致线程之间共享此数据的问题。
根据您的情况,您可以创建一个static final
和不可变列表。
答案 1 :(得分:1)
从技术上讲,您可以拥有变量final
的(引用),并在以后的某个时刻动态填充其内容:
public static final List<String> listPersons = new ArrayList<>();
//...
public void initialize() {
List<String> contents = populateContentsFromEnvironmentVariable();
listPersons.addAll(contents);
}
但是,使用这样的“可变内容”常量会带来可能的问题。例如,您需要确保客户端代码在填充列表之前不会读取该列表。您可能需要重新考虑设计,以便特定于环境的属性仅初始化一次,最好对其进行封装,以便可以通过访问器方法(而不是静态常量)访问它们。这也将允许延迟,按需初始化,缓存等。
答案 2 :(得分:0)
最好的方法是像这样初始化静态列表:
//Static final and unmodifiable list
private static final List<String> listPersons = createListPersons();
private static final createListPersons() {
List<String> listPersonsTemp = getPersonsFromEnvironmentVariable();
return Collections.unmodifiableList(listPersonsTemp);
}
public static final List<String> getListPersons(){
return listPersons;
}
这样,您可以确保您的列表不可修改,并且只能通过getter访问。这样,声纳将不会抱怨访问修饰符。
由于列表包含字符串并且不可修改,因此可以认为它是不可变的。
答案 3 :(得分:0)
修饰符应该以正确的顺序声明 Java 语言规范建议按以下顺序列出修饰符:
1. Annotations
2. public
3. protected
4. private
5. abstract
6. static
7. final
8. transient
9. volatile
10. synchronized
11. native
12. strictfp
不遵循此约定不会产生技术影响,但会降低代码的可读性,因为大多数开发人员都习惯于标准顺序。
不合规的代码示例
static public void main(String[] args) { // Noncompliant
}
合规解决方案
public static void main(String[] args) { // Compliant
}