2023-java-study / book-study

북 스터디 기록 레포지토리
0 stars 0 forks source link

[Item 26] 제네릭 contains() 동작 과정 #91

Open gmelon opened 1 year ago

gmelon commented 1 year ago

p.157 코드 26-5 가 동작은 하지만 안전하지 않다고 했는데 현재 작성된 코드 그대로의 상태에서도 문제가 생길 여지가 있을까요?

예를 들면 s2.contains(o1)에서 s2가 실제로는 Set<String>인데 o1 이 Integer 이면 에러가 나는지가 궁금합니다.

ssstopeun commented 1 year ago
public class wildTest {
    public static void main(String[] args) {
        Set<Integer> s1 = new HashSet<>();
        Set<Integer> s2 = new HashSet<>();

        s1.add(1);
        s2.add(1);

        System.out.println(numElementsInCommon(s1,s2));
    }

    private static int numElementsInCommon(Set s1, Set s2) {
        int result = 0;
        for(Object o1 : s1){
            if(s2.contains(o1)){
                result++;
            }
        }
        return result;
    }
}

이렇게 했을때 둘다 잘 동작했습니다. 코드의 o1이 Object o1 이기 때문에 Integer이든 String이든 o1에 저장이 되고 비교하여 s1에 요소가 있는지 잘 확인이 되는 것 같습니다. 그래서 질문 주신 o1이 Integer일때도 에러가 나지 않습니다.

예시를 작성하면서 로타입이 안전하지 않아서 생기는 문제를 생각하고 작성해보려고했는데 떠오르는게 없었어요......ㅜㅜ 같이 얘기해보면 좋을 것 같아요...


로타입대신 비한정적와일드카드타입을 사용하는 것이 어떤 타입이 와도 상관이없다. 는 것을 주석이 아닌 컴파일러가 이해할 수 있게 명시해줄 수 있어서 좋은 것일까요..?

ssstopeun commented 1 year ago
private static int numElementsInCommon(Set s1, Set s2) {
    int result = 0;
    s1.add(5);

    for(Object o1 : s1){
        if(s2.contains(o1)){
            result++;
        }
    }
    return result;
}

이렇게 set의 타입불변이 깨질수 있겠네요..