2015-01-02 3 views
7

저는 최근 Java Generics를 배우면서 "Java Generics FAQ"를 사용하려고합니다.Java Generics 와일드 카드 혼란

와일드 카드 매개 변수화 된 유형과 관련된 질문 (# 304)이 다소 혼란 스럽습니다. 도움을 주시면 감사하겠습니다.

코드 예 :

boolean equal = box.equalTo(box); 
equal = box.equalTo(new Box<String>("abc")); 

감사

+4

오류는 무엇을 말하고 무엇을 이해합니까? –

+0

@SotiriosDelimanolis는 equalTo()에 대한 매개 변수가 상자 일 것이라고 생각하고 상자 이 "상자"를 허용 할 수없는 이유와 인수로 새 상자 ("abc")을 사용할 수없는 이유를 이해하지 못합니다. – foolhunger

+0

오류가 발생하면 컴파일러 오류 또는 런타임 오류를 의미합니까? – smac89

답변

7
Box<?> box = new Box<String>("abc"); 
box.put("xyz");  // error 
String s = box.take(); // error 
  1. , 당신은 다형성을 사용하고 있습니다. 이 알 수없는 와일드 카드라고 Box<?>

  2. Type<?> 시간을 컴파일에서 그래서, 상자 개체의 유형입니다. 어떤 유형의 Box를 입력했는지 모르기 때문에 해당 객체에서만 읽을 수 있고 Object 인스턴스로 읽은 객체 만 사용할 수 있습니다. 그렇기 때문에 box.put("xyz") 오류가 발생하고 String s = box.take() 오류가 발생합니다. 둘째

는 :

boolean equal = box.equalTo(box); 

equalTo하지 Box<?>Box<T> 수신된다. 위에서 설명한 것처럼 T는 모든 클래스를 나타내지 만 ?은 알 수없는 와일드 카드를 의미하며이 두 용어는 동일하지 않습니다.

그리고 알아 두어야 할 다른 사항. Java에서 generic은 컴파일 타임에 있습니다. C#과 같은 다른 것과 대조적으로, 제네릭은 런타임에 있습니다.Java wildcard

희망이 도움이 :)

5

equalTo 방법은 Box<T>하지 Box<?>

class Box<T> { 
    private T t; 
    public Box(T t) { this.t = t; } 
    public void put(T t) { this.t = t;} 
    public T take() { return t; } 
    public boolean equalTo(Box<T> other) { return this.t.equals(other.t); } 
    public Box<T> copy() { return new Box<T>(t); } 
} 

class Test { 
    public static void main(String[] args) { 
    Box<?> box = new Box<String>("abc"); 
    box.put("xyz");  // error 
    box.put(null);  // ok 

    String s = box.take(); // error 
    Object o = box.take(); // ok 

    boolean equal = box.equalTo(box); // error {confused} 
    equal = box.equalTo(new Box<String>("abc")); // error {confused} 

    Box<?> box1 = box.copy(); // ok 
    Box<String> box2 = box.copy(); // error 
    } 
} 

이 실패라는 이유를 아래의 두 가지 방법을 알아낼 수 없습니다. Box<?> 유형의 객체가있는 경우 Box<String> 또는 심지어 Box<?>equalTo의 매개 변수로 사용할 수 없으므로 두 상자의 유형이 동일하지 않을 수 있으므로 T 유형이 동일하지 않을 수 있습니다.

컴파일러는 컴파일 할 때 정적 유형의 개체를 사용합니다.

Box<?> b = new Box<String>(); 
b.equalTo(new Box<String>("abc"); 

을하지만이되지 않습니다 :

그래서,이 실패합니다

Box<String> b = new Box<String>(); 
b.equalTo(new Box<String>("abc"); 
OOP에서
3

왜이 있기 때문에 그들은 실패

를 실패라는 두 개의 방법 이하 알아낼 수 없습니다 : 여기

은 와일드 카드에 대한 참조 링크입니다 와일드 카드 작동 방법.

와일드 카드는 "우리가 더 이상 알지 못하는 일부 유형"을 나타냅니다.

간단한 클래스를 만들어 보겠습니다.

class Holder<T> { 
    private T obj; 

    void set(T obj) { 
     this.obj = obj; 
    } 

    T get() { 
     return obj; 
    } 
} 

우리가 Holder<?>을 가질 때 우리는 우리가 어떻게 액세스 할 수 있는지에 대한 특별한 규칙을 가지고 있습니다. 특히 generic 인수로 메소드를 호출 할 수 없습니다. 이것은 우리가 더 이상 어떤 유형인지 모르기 때문입니다. 그렇게하면 안전하지 않을 수 있습니다.

우리가 Holder<?> 우리가 개념 상 같은 것을 가지고있을 때 : 우리가 더 이상 무엇인지 모르기 때문에 X이 유형을 의미

class Holder<?> { 
    private X obj; 

    void set(X obj) { 
     this.obj = obj; 
    } 

    Object get() { 
     return obj; 
    } 
} 

이 우리에게-출입 금지입니다.

  • get 반환 Object 그것이 우리가 obj가 확신 할 수있는 유일한 클래스이기 때문에
  • set 나는 이것이 당신의 equalTo 원래 같은 선언으로 인해 경우에 이상하게 보일 수있는 가정의 모든

에서 호출 할 수 없습니다

public boolean equalTo(Box<?> other); 

그러면 전화를 걸 수 있습니다. 그러나 와일드 카드는 T?으로 바꾸기 만하면 작동하지 않습니다.

4
  • Box<?>은 "알 수없는 상자"입니다.
  • Box<? extends String>
  • 는 "적어도 문자열에서 것들의 상자"
  • Box<String> 확실히 이다 "문자열의 상자"가 될 것입니다.
  • 그래서 "알 수없는 상자"가 있고 그 안에 유형 (예 : 문자열)을 넣으려고합니다. 컴파일러는 확실하지 않습니다. 그것의 알 수없는 상자. 실제로 Integers 만 받아 들인다면 어떨까요?
  • null을 "알 수없는 상자"에 넣을 수 있습니까? 확실한.
  • "알 수없는 상자"에서 "얻을 수있는 것"은 무엇입니까? 적어도 하나의 객체.

컴파일러를 요구

Box<?> box = new Box<String>("abc"); 

그것의 약 <String>을 잊고 box는 "알의 상자"가정하는 점을 감안.보는 오류는 컴파일러가 더 이상 인수의 유형 검사를 수행 할 수 없음을 나타냅니다. 주어진 타입이 알려지지 않은 것 (null을 제외하고)에 속하는지 검사 할 수 없습니다.