2014-10-07 3 views
1

Effective Java 2 판 23 항을 연구하면서 혼합 개체의 인수 목록이있는 원시 컬렉션이있는 생성자로 개체를 인스턴스화하려고했습니다. 컴파일러가 생성자에 원시 형식을 전달하려고 시도하고 있다고 생각했습니다. 그러나 컴파일러는 "호출자가 아닌 호출 수신자"라는 확인되지 않은 예외 경고 만 제공합니다.개체 인스턴스화 이전에 매개 변수화 된 형식의 유효성을 확인하는 방법

클래스가 잘 컴파일되어 새로운 코드에서 원시 타입을 사용하지 않도록 Josh Bloch의 진술을 지원합니다. 이것이 컴파일 된 사실은 조금 불안합니다.

Q? 생성자에서 객체 유효성을 수동으로 확인해야하는 것보다 객체를 인스턴스화하기 전에 클래스의 유형 안전성을 보장 할 수있는 방법은 무엇입니까? 다음은 "호출자 ... 기본"에서 확인되지 않은 할당 경고 만 제공했습니다. 어떻게 방어자가이를 방지 할 수 있습니까? 그들이 도입하기 전에, 당신은 어디 입력 된 모음이 예상되는 유형이 지정되지 않은 모음을 사용하여 작성된 코드와 자바 제네릭 호환되도록하기 위해

public class RawType { 

    private final Collection<Example> example; 

    public RawType(Collection<Example> example) { 
     this.example = example; 
    } 

    public Collection<Example> getExample() { 
     return example; 
    } 

    public static void main(String[] args) { 

     Collection unsafe = new ArrayList(); 

     unsafe.add(new Example()); 
     unsafe.add(new Corruption()); 
     unsafe.add(new Example()); 

     RawType rawType = new RawType(unsafe); // Corruption 

     for(Object type : rawType.getExample()) { 
      System.out.println(type.getClass().getName()); // Mixed Classes... 
     } 

    } 

    static class Corruption {} 

    static class Example{} 

} 
+1

이러한 상황을 피하기 위해 경고를 무시하지 마십시오. – Braj

+0

"callee"(생성자)에 경고가 없으므로 경고가 없습니다. 문제는 적절한 제네릭 형식을 사용해야하는 원시 형식을 사용하는 호출자입니다. 피 호출자 측에서도 경고를하기 위해서는 "이 생성자/메서드는 다른 곳에서 올바르게 사용되지 않습니다."라는 말을해야합니다. – kajacx

+0

나는 분명히 "The Caller, in main"API를 만들고 누군가가 원시 타입을 보내고 있다고 생각합니다 ... 수동 검증없이 어떻게 방어 할 수 있습니까? 그것은 질문입니다. –

답변

1

아래 라인은 컴파일되지만 경고도 생성합니다.

Collection unsafe = new ArrayList(); // RAW type 
unsafe.add(1);      // no compile time error (just warning) 

Collection<String> example = unsafe; // assign RAW type to parametrized type 
example.add(1);      // compile time error 

더 나은 사용법 그런 상황을 피하기 위해 일반적인 컬렉션을 작성한 다음 값을 추가하십시오. 절대 혼합 RAW 및 매개 변수화 된 유형.


코드 아래에서보세요 :

Collection<Integer> unsafe = new ArrayList<Integer>(); 
unsafe.add(1); 
Collection<String> example = unsafe; // compile time error 

Read more...


당신은 RAW 형식이 다음 생성자 코드 아래 사용 피할 수없는 경우

Collection unsafe = new ArrayList(); 
unsafe.add(1);      
unsafe.add("hello"); 

// in the constructor, just add String values from the unsafe collection 
Collection<String> example = new ArrayList<String>(); 
for(Object value:unsafe){ 
    if(value instanceof String){ 
     example.add((String)value); 
    } 
} 
+0

내가 이해하려고 시도하는 것은 '호출자'가 인수에서 외부 형식을 보내지 않도록하는 방법입니다. 검증 구현 없이는 준수를 강요하는 것은 불가능한 것처럼 보입니다. –

+0

왜 RAW 유형을 사용하고 있습니까?당신은 그것을 피할 수 있습니까? – Braj

+0

일반은 컴파일 타임 검사에서만 작동합니다. 모든 일반 유형 정보는 런타임에 손실됩니다. – Braj

0

. 따라서 Collection (형식 매개 변수 없음)은 Collection을 필요로하는 생성자로 전달 될 수 있습니다.

그래서 컬렉션에 대한 응답으로 유형이 지정되지 않은 콜레 션에 오브젝트를 추가 할 때주의해야 안전 할 수 있습니다. 런타임을 원하는 경우 컬렉션에서 개체를 검색 할 때 수동으로 개체 유형의 유효성을 검사 할 수 있습니다.

관련 문제