-> 블로그 이전

[Java] 제네릭 만들기

2021. 12. 13. 15:52Language`/Java

제네릭 클래스 작성

- ex) 타입 매개변수 T를 가진 제네릭 클래스 Myclass

- ex) 타입 매개변수 T를 가진 제네릭 클래스 stack (스택 자료구조)

class Myclass<T>{
    T val; // 타입이 T인 변수 val
    void set(T val){
        this.val = val;
    }
    T get(){ // 값 val를 타입 T로 return
        return val;
    }
}

class stack<T>{
    int top; // 스택의 top
    Object [] stack; // item을 저장할 stack 배열
    public stack(){
        top = -1;
        stack = new Object[10];
        // 제네릭 매개변수로는 객체 생성, 배열 생성이 불가능
        // 따라서 Object 배열을 생성해서 실제 타입 객체를 item으로 push
    }
    public void push(T item){
        if(top == 9)
            return;
        else
            stack[++top] = item;
    }
    public T pop(){
        if(top == -1)
            return null;
        return (T)stack[top--];
        // Object 배열로 생성했기 때문에 타입 매개변수 타입으로 강제 캐스팅이 필수
    }
}

 

 

타입 매개변수

- 제네릭 클래스 내에서 제네릭 타입을 가진 객체의 생성은 허용되지 않는다

- 제네릭 매개변수로 객체 생성, 배열 생성 등을 할 수 없다

- 배열을 생성하려면 Object의 배열로 생성하고, 타입 매개변수 타입으로 강제 캐스팅을 해야 한다

public stack(){
        top = -1;
        stack = new Object[10];
        // 제네릭 매개변수로는 객체 생성, 배열 생성이 불가능
        // 따라서 Object 배열을 생성해서 실제 타입 객체를 item으로 push
    }
public T pop(){
        if(top == -1)
            return null;
        return (T)stack[top--];
        // Object 배열로 생성했기 때문에 타입 매개변수 타입으로 강제 캐스팅이 필수
    }
  • Object의 배열로 생성 -> 배열의 요소를 return 할 때 타입 매개변수 타입으로 강제 캐스팅 

 

 

제네릭 메소드

- 타입 매개변수는 메소드의 리턴 타입 앞에 선언

public static <T> stack<T> reverse(stack<T> a){
        // 리턴타입 = stack<T>, 타입 매개변수 = <T>
        stack<T> s = new stack<T>(); // 스택 a를 반대로 저장하는 스택 s
        while(true){
            T tmp; // 교환 변수
            tmp = a.pop();
            if(tmp==null)
                break;
            else
                s.push(tmp);
        }
        return s; 
    }

 

 

제네릭 장점

  1. 동적으로 타입이 결정되지 않고, 컴파일 시에 타입이 결정되어서 안전한 프로그래밍 가능
  2. 런타임 타입 충돌 문제 방지
  3. 개발 시 타입 캐스팅 절차 불필요
  4. ClassCastException 방지