와일드카드(자바)

Wildcard (Java)

Java 프로그래밍 언어에서 와일드카드 ? 는 범용(파라미터화) 타입사용의 타입 안전성을 제어하는 특수한 타입[1] 인수입니다.변수 선언 및 인스턴스화 및 메서드 정의에서 사용할 수 있지만 일반 [2][3]유형의 정의에서는 사용할 수 없습니다.이는 C#Scala에서 볼 수 있는 정의 사이트 분산 주석과 대조적으로 사용 사이트 분산 주석의 한 형태입니다.

일반 유형에 대한 공분산

(Java에서는 공변하는) 배열과 달리, 일반 유형의 다른 인스턴스화는 서로 호환되지 않으며, 심지어 명시적으로도 호환되지 않습니다.선언과 함께Generic<Supertype> superGeneric; Generic<Subtype> subGeneric;컴파일러는 양쪽 캐스팅에 대해 변환 오류를 보고합니다.(Generic<Subtype>)superGeneric그리고.(Generic<Supertype>)subGeneric.

이 비호환성은 와일드카드로 완화될 수 있습니다.?는 실제 유형 파라미터로 사용됩니다.Generic<?>범용 타입의 모든 파라미터리온의 슈퍼 타입입니다.Generic. 이를 통해 타입의 오브젝트가Generic<Supertype>그리고.Generic<Subtype>변수 또는 형식의 메서드 매개변수에 안전하게 할당됨Generic<?>.사용.Generic<? extends Supertype>동일한 기능을 허용하여 호환성을 제한합니다.Supertype그리고 그 자식들.또 다른 가능성은Generic<? super Subtype>양쪽 오브젝트를 모두 수용하여 호환성을 제한합니다.Subtype그리고 그 부모들 모두.

파라미터 유형으로서의 와일드카드

범용 유닛의 본문에서 (공식) 타입 파라미터는 상한(다음으로 표현)과 같이 처리된다.extends;Object제한되지 않은 경우).메서드의 반환 유형이 type 매개 변수인 경우 결과(예: type)?)는 상한(또는Object다른 방향에서는 와일드카드는 다른 타입에도 맞지 않습니다.Object: 만약?메서드의 형식 형식 매개 변수로 적용되었으므로 실제 매개 변수를 전달할 수 없습니다.단, 알 수 없는 타입의 오브젝트는 범용 오브젝트로부터 읽어내어 상한의 슈퍼 타입의 변수에 할당할 수 있다.

학급 포괄적인 < >T 확장 상한> {     사적인 T t;     무효 쓰다(T t) {         이것..t = t;     }     T 읽어주세요() {         돌아가다 t;     } } ... 포괄적인< >상한> concrete Type 참조 = 신규 포괄적인< >상한>(); 포괄적인<?> 와일드카드 레퍼런스 = concrete Type 참조; 상한 ub = 와일드카드 레퍼런스.읽어주세요(); // 오브젝트도 OK입니다. 와일드카드 레퍼런스.쓰다(신규 물건()); // 입력 오류 와일드카드 레퍼런스.쓰다(신규 상한()); // 입력 오류 concrete Type 참조.쓰다(신규 상한()); // OK(확인) 

경계 와일드 카드

경계 와일드카드는 상속 제약 조건이 상한 또는 하한인 와일드카드입니다.와일드카드 바운드는 클래스 유형, 인터페이스 유형, 배열 유형 또는 유형 변수 중 하나입니다.상한은 extensed 키워드를 사용하여 나타내고 하한은 super 키워드를 사용하여 나타냅니다.와일드카드는 상한 또는 하한 중 하나를 나타낼 수 있지만 둘 다 지정할 수는 없습니다.

상한

와일드카드의 상한은 대응하는 범용 타입으로 선언된 해당 타입 파라미터의 상한 서브타입이어야 합니다.상한을 명시적으로 나타내는 와일드카드의 예를 다음에 나타냅니다.

Generic<? extends SubtypeOfUpperBound> referenceConstrainedFromAbove;

이 참조에는, 다음의 파라메타화를 포함할 수 있습니다.Generic그 타입 인수는 서브타입이다.SubtypeOfUpperBound상한을 명시적으로 나타내지 않는 와일드카드는 제약이 있는 와일드카드와 실질적으로 동일합니다.extends ObjectJava의 모든 참조 유형은 객체의 하위 유형이기 때문입니다.

하한

다음과 같은 하한 와일드카드

Generic<? super SubtypeOfUpperBound> referenceConstrainedFromBelow;

모든 파라미터화를 유지할 수 있다Genericany type 인수가 대응하는 type 파라미터 상한의 서브타입과 슈퍼타입인 경우SubtypeOfUpperBound.

와일드카드를 사용한 객체 생성

와일드카드 유형 인수를 사용하여 개체를 생성할 수 없습니다. 예를 들어,new Generic<?>()는 금지되어 있습니다.유형 변수에 할당할 수 있는 개체를 만들려는 경우 실제로는 이 작업이 필요하지 않습니다.Generic<?>type 인수로서 임의의 타입(와일드카드의 제약에 해당하는 경우)을 사용할 수 있습니다.

하지만,new ArrayList<Generic<?>>()와일드카드는 인스턴스화된 유형의 파라미터가 아니기 때문에 허용됩니다.ArrayList에 대해서도 마찬가지입니다.new ArrayList<List<?>>().

어레이 생성 식에서 어레이의 컴포넌트 유형은 Java Language Specification 섹션 4.7에 정의된 대로 재작성 가능해야 합니다.여기에는 어레이의 컴포넌트 타입에 타입 인수가 있는 경우 모두 무제한 와일드카드(와일드카드)여야 합니다.?). 예를 들어,new Generic<?>[20]맞는데 반해new Generic<SomeType>[20]그렇지 않습니다.

두 경우 모두 매개 변수를 사용하지 않는 것도 다른 옵션입니다.이렇게 하면 유형 안전성이 떨어지기 때문에 경고가 발생합니다(Raw 유형 참조).

예: 리스트

Java Collections Framework에서 클래스는List<MyClass>유형 객체의 정렬된 컬렉션을 나타냅니다.MyClass. 상한은 다음과 같이 지정됩니다.extends: AList<? extends MyClass>의 서브클래스의 오브젝트 리스트입니다.MyClass예를 들어, 목록에 있는 모든 객체의 유형이 보장됩니다.MyClass타입 변수를 사용하여 반복할 수 있습니다.MyClass[4]

일반의 무효 어떻게 좀 해봐.(목록.<? 확장 마이클래스> 목록.) {     위해서 (마이클래스 물건 : 목록.) { // OK(확인)         // 뭔가를 하다     } } 

단, 타입의 오브젝트를 추가할 수 있는 것은 아닙니다.MyClass이 목록으로:

일반의 무효 어떻게 좀 해봐.(목록.<? 확장 마이클래스> 목록.) {     마이클래스 m = 신규 마이클래스();     목록..더하다(m); // 컴파일 오류 } 

다음과 같이 지정되는 하한의 경우 그 반대의 경우도 마찬가지입니다.super: AList<? super MyClass>슈퍼클래스의 오브젝트 리스트입니다.MyClass예를 들어, 리스트는 모든 유형의 개체를 포함할 수 있습니다.MyClass임의의 타입의 오브젝트를 추가할 수 있습니다.MyClass:

일반의 무효 어떻게 좀 해봐.(목록.<? 잘 하는 군요 마이클래스> 목록.) {     마이클래스 m = 신규 마이클래스();     목록..더하다(m); // OK(확인) } 

단, 유형 변수를 사용하여 해당 목록을 반복할 수 있는 것은 아닙니다.MyClass:

일반의 무효 어떻게 좀 해봐.(목록.<? 잘 하는 군요 마이클래스> 목록.) {     위해서 (마이클래스 물건 : 목록.) { // 컴파일 오류         // 뭔가를 하다     } } 

두 가지 작업을 모두 수행하려면 유형 개체를 추가합니다.MyClass목록으로 이동하여 유형 변수를 사용하여 반복한다.MyClass,aList<MyClass>필요한 것은 이 타입뿐입니다.List둘 다List<? extends MyClass>그리고.List<? super MyClass>를 클릭합니다.[5]

Joshua Bloch가 쓴 "Effective Java"에 나오는 니모닉스 PECS(Productor Extensions, Consumer Super)"는 Java에서 와일드카드(공분산 및 반분산 대응)를 언제 사용해야 하는지를 쉽게 기억할 수 있는 방법을 제공합니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ "Chapter 4. Types, Values, and Variables". docs.oracle.com. Retrieved 2020-11-03.
  2. ^ Gilad Bracha (June 2004), "4. Wildcards", Generics in the Java Programming Language (PDF), retrieved 6 March 2016
  3. ^ "8.1.2 Generic Classes and Type Parameters", The Java Language Specification, Oracle, retrieved 6 March 2016
  4. ^ 상속(개체 지향 프로그래밍)
  5. ^ Java 구문(일반)