Sonar rule java:S2386 not working properly

Sonarqube - v10.6 (92116)
Sonar lint 10.7.0.78874, in IDE IDEA
Java
S2386

It is showing me false positive, because it doesn’t include Arrays.asList in rule.

    public static final List<String> TEST = Arrays.asList(
            "a", "b", "c", "d"
    );

Sonar will show this rule in this example, though it is impossible to modify the collection. If you try add/remove item, it will throw exception not supported operation. So, this collection is already immutable.

Hello @podhorsky-ksj and welcome to the Sonar Community.

Thank you for reporting this inconsistency. According to the Oracle’s java.util.Arrays specs the returned list is modifiable, anyway the implementation is not overriding any add and remove methods from the AbstractList that by default are unsupported.

I’ve created [SONARJAVA-5094] - Jira to avoid raising an issue in this case; at least, meanwhile, Oracle fixes this inconsistency.

Cheers,
Angelo

Hi there!

I believe the warning is justified in this case as the list returned by Arrays.asList is mutable, just not resizable, as is described in the documentation linked above. You can still use List.set, List.replaceAll etc. to modify elements:

public class Main {
	public static final List<String> TEST = Arrays.asList(
		"a", "b", "c", "d"
	);

	public static void main(String[] args) {
		TEST.set(0, "e");
		System.out.println(TEST); // [e, b, c, d]
		TEST.replaceAll(String::toUpperCase);
		System.out.println(TEST); // [E, B, C, D]
	}
}

Try it online!

As of Java 9 there’s the option of using List.of(E...), which is truly immutable. In earlier versions, Collections.unmodifiableList(List) together with Arrays.asList can be used just as well.

3 Likes

Thank you, @ivaniesta14, for looking into it; you’re correct, indeed. Quoting from the specifications:

The returned list implements the optional Collection methods, except those that would change the size of the returned list. Those methods leave the list unchanged and throw UnsupportedOperationException.