Notice
Recent Posts
Recent Comments
Link
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

블로그 이름 뭐하지

[JAVA] 제네릭 본문

JAVA

[JAVA] 제네릭

가는말이고우면오는말은come 2024. 9. 24. 14:53

타입을 일반화하는 것.

클래스 내부에서 개별적으로 타입을 지정하지 않고,

외부(인스턴스 생성 시, 메서드 호출 시)에서 타입을 지정한다.

class MyArray{

    int element;
    void setElement(int element) { this.element = element; }
    int getElement() { return element; }

}

일반적인 타입지정△------제네릭사용▽

class MyArray<T> {

    T element;
    void setElement(T element) { this.element = element; }
    T getElement() { return element; }

}

//외부에서 타입을 지정한다.
MyArray<Integer> myArr01 = new MyArray<Integer>;
MyArray<Double> myArr02 = new MyArray<Double>;

 

제네릭의 효용

1) 타입 언어에서 중복되거나 필요없는 코드를 줄여준다.

2) 타입 안정성을 해치지 않는다.

 

제네릭 문법

클래스, 메서드에 사용하며, 클래스 이름 뒤에 <>을 붙이고 타입변수를 지정한다.

타입변수는 임의의 참조형 타입을 의미하고, T 뿐 아니라 어떠한 문자가 들어가도 상관없다.

여러 개의 타입변수는 쉼표(,)로 구분하여 사용한다.

 

제한

1) 제네릭은 static 멤버에 사용할 수 없다.

(Bc static 멤버는 인스턴스 변수로 간주되고, 모든 객체에 동일하게 동작해야 하므로)

2) 제네릭 배열을 생성할 수 없다.

//제내릭 클래스(원시타입)
//<>안에 타입변수T
public class Generic<T> {
    private T t;
    
    public T get() {
        return this.t;
    }
    public void set(T t) {
        this.t = t;
    }

    public static void main(String[] args) {
        //선언 >> T = String
        Generic<String> stringGeneric = new Generic<>();
        
        stringGeneric.set("Hello World");
				
        String tValueTurnOutWithString = stringGeneric.get();

        System.out.println(tValueTurnOutWithString);
    }
}

 

문법

1) 다수의 타입변수 사용가능

public class Generic<T, U, E> { // 다수의 타입변수 T, U, E 사용
    public E multiTypeMethod(T t, U u) { ... }
}

Generic<Long, Integer, String> instance = new Generic();
instance.multiTypeMethod(longVal, intVal);

 

2) 상속과 타입의 관계는 그대로 적용

(ex. 부모 클래스로 제네릭 타입 변수 지정 >> 그 안에 자식 클래스를 넘기는 것도 동작함)

 

3) 와일드 카드로 제네릭의 제한을 정할 수 있음

<? extends T> : T클래스와 그 자식클래스만 사용가능

<? super T> : T클래스와 그 부모클래스만 사용가능

<?> : 제한 없음

//<? extends class> : class와 그 자손들만 사용가능
public class ParkingLot<T extends Car> { ... }

ParkingLot<BMW> bmwParkingLot = new ParkingLot();
ParkingLot<Iphone> iphoneParkingLot = new ParkingLog(); // error!

 

4) 메서드를 스코프로 제네릭을 별도로 선언할 수 있음

반환 타입 앞에 제네릭을 사용한 경우 해당 메서드에만 적용되는 제네릭 타입 변수를 선언할 수 있다.

제네릭 클래스의 타입변수를 static 메서드에서는 사용할 수 없으나,

제네릭 메서드의 제네릭 타입변수는 메서드 하나를 기준으로 선언하고 사용할 수 있다.

같은 이름의 변수를 사용해도 제네릭 메서드의 타입변수는 제네릭 클래스의 타입 변수와는 다르다.

//불가능
//Student 클래스가 인스턴스화 하기 전에 static은 메모리에 올라가는데
//name의 타입인 T가 결정되어 있지 않기 때문.
public class Student<T> {
  
    static T getName(T name) {   
        return name;
    }
}

//가능
//제네릭 메서드는 호출시에 매개타입을 지정하기 때문.
//Student 클래스에서 지정한 <T>와 제네릭 메서드의 <T>는 별개의 타입변수다.
public class Student<T> {
    
    static <T> T getOneStudent(T id) {
        return id;
    }
}

 

 

 

'JAVA' 카테고리의 다른 글

[JAVA] 모던 자바 : 람다식과 스트림  (0) 2024.09.26
[JAVA] 쓰레드  (0) 2024.09.25
[JAVA] 예외 처리  (0) 2024.09.24
[JAVA] 추상 클래스와 인터페이스  (0) 2024.09.23
[JAVA] 상속  (0) 2024.09.23