"안녕하세요! 제네릭에 대한 Ellie의 수업을 계속하겠습니다. 들을 준비가 되셨습니까?"

"예."

"그럼 시작하겠습니다."

"가장 먼저 알아야 할 것은 클래스의 메서드도 자체 유형 매개변수를 가질 수 있다는 것입니다."

"알아요."

"아니요, 구체적으로 자신 의 유형 매개변수를 의미합니다. "

class Calculator
{
  T add(T a, T b); // Add
  T sub(T a, T b); // Subtract
  T mul(T a, T b); // Multiply
  T div(T a, T b); // Divide
}

"이 유형 매개변수는 특히 메서드와 관련이 있습니다. 클래스에는 매개변수가 없습니다. 이러한 메서드를 정적으로 선언하고 개체 없이 호출할 수도 있습니다."

"그렇군요. 메소드의 타입 파라미터 포인트는 클래스와 같은 건가요?"

"예. 하지만 새로운 것이 있습니다."

"이미 알고 있듯이 유형 선언에 와일드카드를 사용할 수 있습니다. 그런 다음 다음 상황을 상상해 보십시오."

예 1
public void doSomething(List<? extends MyClass> list)
{
 for(MyClass object : list)
 {
  System.out.println(object.getState()); // Everything works well here.
 }
}

"하지만 컬렉션에 새 항목을 추가하려면 어떻게 해야 합니까?"

예 2
public void doSomething(List<? extends MyClass> list)
{
 list.add(new MyClass()); // Error!
}

"문제는 일반적인 경우 doSomething 메소드가 요소가 MyClass 객체가 아니라 MyClass 하위 클래스의 객체인 List를 전달할 수 있다는 것입니다. 그러나 이러한 목록에 MyClass 객체를 추가할 수는 없습니다!"

"아. 그럼 어떻게 하면 될까요?"

"아무것도 아닙니다. 이 상황에서는 아무것도 할 수 없습니다. 하지만 이것은 Java 제작자에게 생각할 거리를 제공했습니다. 그리고 그들은 새로운 키워드인 super 를 생각해 냈습니다 ."

"구문은 거의 동일하게 보입니다."

List<? super MyClass> list

그러나 extends와 super 사이에는 중요한 차이점이 있습니다.

"«? extends T»는 클래스가 T의 자손이어야 함을 의미합니다."

"«? super T»는 클래스가 T의 조상이어야 함을 의미합니다."

"성모리. 그럼 이건 어디에 쓰는 거지?"

"«? super T»는 방법이 T 개체 모음에 추가하는 것과 관련될 때 사용됩니다. 이 경우 T 개체 모음이거나 T의 조상일 수 있습니다."

"아. AT 객체는 유형이 T의 조상 중 하나인 참조 변수에 할당될 수 있습니다."

"솔직히 이 접근 방식은 자주 사용되지 않습니다. 게다가 단점도 있습니다. 예를 들면 다음과 같습니다."

public void doSomething(List<? super MyClass> list)
{
 for(MyClass object : list) // Error!
 {
  System.out.println(object.getState());
 }
}
public void doSomething(List<? super MyClass> list)
{
 list.add(new MyClass()); // Everything works well here.
}

"이제 첫 번째 예가 작동하지 않습니다."

"목록이 List<Object>일 수도 있기 때문에(Object는 MyClass의 최상위 수퍼클래스임) 본질적으로 다음과 같은 유효하지 않은 코드를 작성하고 있습니다."

예 1
List<Object> list; 

for(MyClass object : list) // Error!
{ 
 System.out.println(object.getState()); 
}

"그렇군요. 재미있는 수업 감사합니다."

"천만에요."