본문 바로가기
카테고리 없음

정보처리기사) 자바 문제_제네릭 클래스

by chuyj15 2025. 2. 27.
728x90
반응형
SMALL

19. 다음은 Java 코드에 대한 문제이다. 아래 코드를 확인하여 알맞는 출력값을 작성하시오.

 

class Main {
 
  public static class Collection<T>{
    T value;
 
    public Collection(T t){
        value = t;
    }
 
    public void print(){
       new Printer().print(value);
    }
 
   class Printer{
      void print(Integer a){
        System.out.print("A" + a);
      }
      void print(Object a){
        System.out.print("B" + a);
      } 
      void print(Number a){
        System.out.print("C" + a);
      }
   }
 }
 
  public static void main(String[] args) {
      new Collection<>(0).print();
  }
  
}


 답(드래그하면 보임) :  B0

 


해설 :

 

 

코드 분석

new Collection<>(0).print();
  • Collection<T> 객체를 생성하면서 0을 인자로 넘김.
  • 0은 int 타입이지만, 제네릭 T가 있으므로 Integer로 박싱됨.
  • print() 메서드를 호출하면 내부 Printer 클래스의 print(value)가 실행됨.

1. 제네릭 클래스 Collection<T>

public static class Collection<T> { T value; public Collection(T t) { value = t; } 
public void print() { new Printer().print(value); } }
  • 제네릭 Collection<T> 클래스는 T 타입의 값을 저장하는 value 변수를 가짐.
  • print() 메서드는 내부 클래스 Printer의 print(value)를 호출.

2. 내부 클래스 Printer

class Printer { 
    void print(Integer a) { System.out.print("A" + a); } 
    void print(Object a) { System.out.print("B" + a); } 
    void print(Number a) { System.out.print("C" + a); } 
}
  • 오버로딩된 print() 메서드가 있음.
    • print(Integer a) → "A" + a
    • print(Object a) → "B" + a
    • print(Number a) → "C" + a
  • print() 메서드는 인자의 타입에 따라 가장 적절한 메서드를 선택함.

핵심: 오버로딩 메서드 선택 과정

1. new Collection<>(0)

  • 제네릭 T는 Integer로 추론됨.
  • 따라서 value = 0은 Integer 타입.

2. new Printer().print(value);

  • value는 Integer 타입.
  • print(Integer a), print(Object a), print(Number a) 중에서 어떤 게 호출될까?

자바의 오버로딩 메서드 선택 규칙

  1. 정확히 일치하는 타입이 있으면 그걸 선택
    • print(Integer a) 가능 (정확히 Integer)
  2. 여러 개의 메서드가 가능하면 가장 구체적인 타입 선택
    • Integer는 Object와 Number의 하위 타입이므로 print(Number a)와 print(Object a)도 가능.
    • print(Integer a)가 가장 구체적인 메서드라서 선택될 것 같지만...

문제는 컴파일 단계에서 제네릭의 타입 정보가 사라지는 것! (타입 소거)

  • Collection<T>는 런타임 시점에 T가 어떤 타입인지 모름.
  • 즉, value의 타입이 Integer인지 알 수 없고, 대신 Object로 취급됨.
  • 그래서 print(Object a)가 호출됨.

결과

B0
  • print(Object a)가 선택됨.
  • 출력: "B" + 0 → B0

정리

왜 print(Integer a)가 아니라 print(Object a)가 호출될까?

  • 제네릭은 컴파일 시점에 타입을 체크하지만, 런타임에는 타입 정보가 사라짐 (타입 소거, Type Erasure)
  • Collection<T> 내부에서 value는 결국 Object로 간주됨.
  • 따라서 print(Object a)가 호출됨.

이제 이해됐지? 😊

728x90
반응형
LIST