⚠️주의⚠️: 해당 문서는 역자의 능력 부족으로 인해 의역이 많이 들어갔습니다. Contribution을 환영합니다.
문서에 따르면,
value-based class
에서 같은 값을 가리키는 두개의 참조 객체를 다르게 구분한다면, 예상치 못한 문제가 발생할 수 있습니다. 특히, 그런 상황에서 synchronization 하거나 hash 값으로 동등성을 체크하려 한다거나, 직렬화 하려할 때 등에 문제가 발생합니다.
이는 value-based class
가 단순히 value 타입의 wrapper가 되는 것을 의도하고 만들어졌기 때문입니다.
value-based class
의 인스턴스
- 접근 가능한 생성자가 없지만, 대신 반환된 인스턴스의 ID에 대해 약속하지 않는 팩토리 메서드를 통해 인스턴스화됩니다
이는 즉, value-based class
의 인스턴스에 lock을 걸려는 사람이, 당신밖에 없는, 유일한 사용자라고 보장하지 못한다는 의미입니다.
따라서 코드가 경합을 일으키고 deadlock 문제에 노출됩니다.
Java 8에서 이 규칙을 위반한다고해서 코드가 실제로 깨진다고 할 수 는 없습니다. 하지만 그렇다고 제대로 동작할 것이라고 보장 할 수도 없습니다.
이 규칙은 이미 알려진 value-based class
가 synchronization
에 사용될 때 경종을 울립니다.
-
java.time
패키지 내의Clock
을 제외한 모든 클래스 - 캘린더의 대인이 될 수 있는 Date 클래스:
HijraDate
,JapaneseDate
,MinguDate
,ThaiBuddistDate
- Optional 클래스들:
Optional
,OptionalDouble
,OptionalLong
,OptionalInt
참고: 이 규칙은 프로젝트의 sonar.java.source의 값이 8보다 낮은 경우(java8) 검사하지 않습니다.
규칙을 어긴 코드
Optional<Foo> fOpt = doSomething();
synchronized (fOpt) { // 규칙을 어긴 코드
// ...
}
같이보면 좋은 자료
-
Value-based classes
java.util.Optional
andjava.time.LocalDateTime
같은 클래스를 보고 Value-based class 라고 부릅니다.
<역>역>
@Test
public void test() {
Optional<String> a = Optional.of("foo");
Optional<String> b = Optional.of("foo");
System.out.println(a == b); // 출력값: false
System.out.println(a.equals(b)); // 출력값: true
}
위 코드에서 a와 b는 “foo”라는 immutable을 참조하고 있어서 같은 value를 가르키고 있습니다.
Optional은 value-based class이기 때문에, 원칙상 내부 값이 같은 a와 b는 같은 값입니다.
하지만 a와 b의 참조가 다릅니다.
그래서 a == b
는 false를 반환하지만, Optional이 equals를 재정의하여 내부 값이 같으면 같은 값으로 인지하도록 해두었으므로 a.equals(b)
는 true를 반환합니다.
If you like SONARKUBE, don’t forget to give me a star.