Open DaeAkin opened 4 years ago
public final class Boolean implements java.io.Serializable,
Comparable<Boolean> {
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
}
Boolean 클래스를 보면 정적 변수로 Boolean 객체를 선언했습니다. 이 객체는 실행시 JVM 메모리의 Method Area에 자리를 차지하게 됩니다.
프로그래머가 Boolean.valueOf(true) 정적 팩터리 메서드를 반복적으로 호출 해도 미리 만들어논 정적 변수를 리턴하기 때문에, 같은 주소를 가진 객체를 리턴하게 됩니다.
boolean value = true;
Boolean aV = Boolean.valueOf(value);
Boolean bV = Boolean.valueOf(value);
aV == bV // true
이렇게 미리 만들어논 정적 변수를 사용함으로써 얻을 수 있는 이득은, 정적 팩터리 메서드로 객체를 생성할 때, 새롭게 객체를 생성하지 않고, 미리 만들어 논 객체를 리턴함으로써 성능상의 이득이 있습니다.
그러나 객체를 수정하게 되면, 같은 객체를 사용하고 있는 다른 코드에도 영향을 미치게 됩니다. 이러한 상황을 방지하기 위해서는 객체의 상태를 조작할 수 있는 메서드(예를 들어 setter 같은)가 없어야 합니다.
@hongji3354 맞아요. 그렇기 때문에, 저렇게 return 된 객체들은 값을 변경할 수 없어야 합니다.
오 삭제를 해도 기록이 남나 보군요ㅋㅋㅋ
근데 위와같은 설명이라면 아래 코드에서 d의 값도 false로 변경되어야 하지 않나요?
public static void main(String[] args) {
boolean a = true;
boolean b = true;
Boolean c = Boolean.valueOf(a);
Boolean d = Boolean.valueOf(b);
System.out.println(c == d);
c = false;
System.out.println(c);
System.out.println(d);
}
c = false; 을 하게 되면, 컴파일러가 c = Boolean.valueOf(false); 로 재할당 하기 때문에 d의 값에는 변경이 없을 것 같습니다
-- 수정 위에 링크 예제는 잘못됐습니다.
반환타입을 하위자료형으로 리턴할 수 있다는데 예제는 뭐가 있을까? EnumSet의 noneOf 메소드는, Enum의 갯수가 64개이상일때와 이하일때 서로 다른 하위 자료형을 반환한다.
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
인스턴스를 새로 생성 하지 않는다고 하는데 이것을 코드로 설명과 반례 Boolean 클래스 같은경우 내부에 캐시된 객체를 재사용 하지만 LocalDateTime 같은 경우 항상 새로운 객체를 반환한다.
public static LocalDateTime of(int year, Month month, int dayOfMonth, int hour, int minute) {
LocalDate date = LocalDate.of(year, month, dayOfMonth);
LocalTime time = LocalTime.of(hour, minute);
return new LocalDateTime(date, time);
}
이 JDK 예제를 보았을 때, 인스턴스를 새로 생성하지 않는 다는 말은, 정적 팩토리 메서드의 장점 중 하나 일뿐, 내부 구현체에 따라 캐싱할지 말지 선택할 수 있는 것 같다.
정리
질문 목록
마무리
동현의 질문
책 내용에서 정적 팩터리 메소드로 객체를 생성하면, 불변 값 클래스에서 동치인 인스턴스가 단 하나뿐임을 보장할 수 있다.(a == b 일때만 a.equals(b)가 성립). 이라고 나와 있어요. 이 문구가 잘 이해가 되지 않네요. 불변 객체를 생성해서 스레드 안전성을 갖는다는 의미인지? 이것도 아닌것 같은데..