According to the documentation,
A program may produce unpredictable results if it attempts to distinguish two references to equal values of a value-based class, whether directly
via reference equality or indirectly via an appeal to synchronization…
This is because value-based classes are intended to be wrappers for value types, which will be primitive-like collections of data (similar to
struct
s in other languages) that will come in future versions of Java.
Instances of a value-based class …
- do not have accessible constructors, but are instead instantiated through factory methods which make no commitment as to the identity of
returned instances;
This means that you can’t be sure you’re the only one trying to lock on any given instance of a value-based class, opening your code up to
contention and deadlock issues.
Under Java 8 breaking this rule may not actually break your code, but there are no guarantees of the behavior beyond that.
This rule raises an issue when a known value-based class is used for synchronization. That includes all the classes in the java.time
package except Clock
; the date classes for alternate calendars, HijrahDate
, JapaneseDate
,
MinguoDate
, ThaiBuddhistDate
; and the optional classes: Optional
, OptionalDouble
,
OptionalLong
, OptionalInt
.
Note that this rule is automatically disabled when the project’s sonar.java.source
is lower than 8
.
Noncompliant code example
Optional<Foo> fOpt = doSomething();
synchronized (fOpt) { // Noncompliant
// ...
}