코딩일기/자격증

[정보처리기사] [Java] 제네릭(Generic) | 2024년 3회 정보처리기사 실기 기출문제

jhy_2023 2025. 6. 25. 22:31
728x90
반응형

2024년 3회 정보처리기사 실기 기출문제

문제

다음 Java 코드를 실행했을 때 출력 결과를 쓰시오.

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 class Main {
    public static void main(String[] args) {
        new Collection<>(0).print();
    }

    public static class Collection<T> {
        T value;

        public Collection(T t) {
            value = t;
        }

        public void print() {
            new Printer().print(value);
        }
    }
}

정답

B0
반응형

해설

📌 기본 개념

1️⃣ 오버로딩(Overloading)

class Printer {
    void print(Integer a) {
        System.out.println("A" + a);
    }
    void print(Object a) {
        System.out.println("B" + a);
    }
    void print(Number a) {
        System.out.println("C" + a);
    }
}
  • 오버로딩이란 같은 이름의 메서드매개변수의 타입, 개수, 순서가 다르게 정의하는 것. 메서드 이름은 같지만 서로 다른 기능을 수행하게 할 수 있음.
  • 위의 경우 print() 메서드는 세 번 오버로딩되어 있음. 전달되는 인자의 타입이 Integer, Object, Number 중 무엇인지에 따라 호출되는 메서드가 다름.

2️⃣ 제네릭(Generic)

public class Box<T> {
    T value;
    public Box(T value) {
        this.value = value;
    }
    public T getValue() {
        return value;
    }
}
  • 제네릭이란 클래스나 메서드를 작성할 때 특정 타입에 의존하지 않고, 호출 시점에서 타입을 지정할 수 있게 하는 기능.
  • public class Box<T>
    • Box라는 이름의 클래스를 만들겠다는 뜻.
    • 여기서 <T>는 타입(Type)의 약자. <T>는 타입 파라미터로, 아직 타입이 무엇인지 정하지 않았다는 의미
  • public Box(T value) {
    • 박스를 만들 때 그 안에 어떤 값을 넣을지 정하는 생성자.
    • T 타입의 값을 받아 value 변수에 저장
  • public T getValue() {
    • 저장된 값을 꺼내는 메서드로, 저장된 타입 그대로 반환
Box<String> strBox = new Box<>("Hello");
String s = strBox.getValue();  // "Hello" 꺼내기

Box<Integer> intBox = new Box<>(123);
int n = intBox.getValue();     // 123 꺼내기

 

  • Box<String> → 문자열 전용 박스
  • Box<Integer> → 숫자 전용 박스

3️⃣ Object와 타입 소거(Type Erasure)

  • Object 클래스
    • 자바의 모든 클래스는 자동으로 Object 클래스를 상속받는다.
    • Object는 자바 클래스의 최상위 부모 클래스로, 모든 객체의 공통 조상
  • 타입 소거(Type Erasure)
    • 제네릭은 컴파일 시점에 타입 체크를 하지만, 실제 실행(런타임) 시에는 타입 정보가 사라진다. 이 과정을 타입 소거(Type Erasure)라 한다. 
    • 타입 소거(Type Erasure) 예시
// 제네릭 박스 클래스
public class Box<T> {
    private T value;

    public Box(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }
}

컴파일러는 위 코드를 다음과 같이 변환

// 타입 소거 후 내부 코드 (의사 코드)
public class Box {
    private Object value;

    public Box(Object value) {
        this.value = value;
    }

    public Object getValue() {
        return value;
    }
}
  • 런타임에는 모든 제네릭 타입이 내부적으로 Object 타입으로 처리
  • 따라서 Box<String>, Box<Integer> 모두 실제 실행은 Object를 담는 박스로 동작
728x90

📌 문제 해설

public class Main {
    public static void main(String[] args) {
        new Collection<>(0).print();
    }

    public static class Collection<T> {
        T value;

        public Collection(T t) {
            value = t;
        }

        public void print() {
            new Printer().print(value);
        }
    }
}

1️⃣ main() 메서드 실행

public static void main(String[] args) {
    new Collection<>(0).print();
}
  • Collection<>(0) → Collection 객체 생성
  • 숫자 0을 통해 제네릭 타입 T는 Integer로 추론됨.
    → 즉, Collection<Integer> collection = new Collection<>(0);와 동일한 상태.
  • 이후 .print() 메서드 호출.

2️⃣ Collection 클래스 생성자 실행

public Collection(T t) {
    value = t;
}
  • t 값은 숫자 0 (정수형 리터럴).
  • 자바는 숫자 값을 클래스 타입인 Integer 객체로 자동 변환해서 저장함.
  • 현재 상태
    value = Integer(0) 형태로 존재

3️⃣ print() 메서드 실행

public void print() {
    new Printer().print(value);
}
  • Printer 클래스 객체 생성.
  • Printer 객체의 print(value) 메서드 호출.

4️⃣ Printer 클래스에서 print 메서드 선택 과정

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);
}
  • Printer 클래스에는 위와 같이 3개의 메서드 오버로딩이 존재
  • 자바에서 메서드 오버로딩은 컴파일 시점 변수의 타입을 기준으로 결정됨
T value;
  • value는 제네릭 타입인 T로 선언되어 있습니다.
  • 제네릭 타입 T는 컴파일 시점에 구체적인 타입이 존재하지 않기 때문에, 제네릭을 처리할 때 타입 소거(Type Erasure) 방식을 사용. 따라서 컴파일 과정에서 제네릭 타입 T는 모두 Object로 변환
  • 즉, value 변수는 컴파일 시점에 Object 타입으로 인식되고, Printer.print(value)를 호출하면, 오버로딩된 메서드 중 가장 범위가 넓은 print(Object a) 메서드가 선택됨

5️⃣ print(Object a) 메서드 실행

void print(Object a) {
    System.out.print("B" + a);
}
  • 문자열 "B"와 a 값을 연결하여 출력.
  • a는 내부적으로 Integer(0) 객체지만, Object 타입으로 전달됨.
  • → 문자열 결합 결과 "B0" 출력됨.

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

728x90
반응형