Closed gmelon closed 1 year ago
책에서 참조를 바깥으로 반환하는 건 안전하지 않다
고 말한 부분이 몇 페이지인지 알수 있을까요??
@NuhGnod 헉 제가 페이지를 안 적었군요 List.of() 관련 내용은 p.195 하단부터 p.196 상단부분 이고
참조를 바깥으로 반환하는 건 안전하지 않다
이 부분은 p.193 입니다.
p.193에서 말하는 배열의 참조
는 매개변수 배열의 참조를 의미한다고 생각합니다.
그래서 코드 32-2는 실제로 파라미터가 T...args
인데 이로 인해 생성된 매개변수 배열 return args
로 밖으로 참조를 내보내고 있어, 클라이언트에서 접근가능합니다.
음 저는 우선 List.of 메서드가 참조를 밖으로 노출하지 않는다고 생각했습니다. 그 이유는 List.of()메소드가 다중정의되어있긴하지만, 반한되는 값들은 같 list를 반환해서 몇개만 보면 됩니다.
@SafeVarargs
ListN(E... input) {
// copy and check manually to avoid TOCTOU
@SuppressWarnings("unchecked")
E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input
for (int i = 0; i < input.length; i++) {
tmp[i] = Objects.requireNonNull(input[i]);
}
elements = tmp;
}
List12(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
static <E> List<E> of() {
return ImmutableCollections.emptyList();
}
static final List<?> EMPTY_LIST = new ListN<>();
static <E> List<E> emptyList() {
return (List<E>) ListN.EMPTY_LIST;
}
static <E> List<E> of(E e1, E e2) {
return new ImmutableCollections.List12<>(e1, e2);
}
static <E> List<E> of(E e1, E e2, E e3) {
return new ImmutableCollections.ListN<>(e1, e2, e3);
}
인수갯수에 맞춰, 인스턴스 생성자의 파라미터로 넘겨주는 형태임.
@SafeVarargs
@SuppressWarnings("varargs")
static <E> List<E> of(E... elements) {
switch (elements.length) { // implicit null check of elements
case 0:
return ImmutableCollections.emptyList();
case 1:
return new ImmutableCollections.List12<>(elements[0]);
case 2:
return new ImmutableCollections.List12<>(elements[0], elements[1]);
default:
return new ImmutableCollections.ListN<>(elements);
}
}
결국 위 ListN생성자를 보면 varargs매개변수를 사용했고, 안전하다는게 보장되었으니(p.195의 2조건 만족) @SafeVarargs 어노테이션을 사용했습니다.
그리고, 참조를 바깥으로 내보냈냐를 보면, E...input
의 input 배열의 참조를 내보내야하는데,
우선 내부에서 사용되는 elements배열은 new Object[]
로 새롭게 생성된 배열이 input배열의 참조에 관여되지 않았습니다.
그래서 저는 input배열은 varargs의 목적대로만 쓰였기 때문에(p.193상단) 메서드가 안전하고 또한, 참조도 밖으로 노출되지 않았다고 생각합니다.
그래서 저는 List.of가 안전한 이유는 item32와 관련지어 본다면, 참조를 밖으로 내보내지 않음에 있다고 생각합니다.
그럼 List는 input하는 배열의 참조가 아닌 내용을 새로 배열을 생성해 저장하고 이 배열의 참조를 return하는 것으로 이해했는데 맞을까요?
네 저는 그렇게 생각했습니다
List.of()는 생성한 List의 참조를 바깥으로 반환합니다. 책에서는 참조를 바깥으로 반환하는 건 안전하지 않다고 하는데
List.of()의 경우 이게 안전할 수 있는 이유는