반응형

이 게시물은 다음 링크를 참조하여 학습했습니다.

 

자바 [JAVA] - 제네릭(Generic)의 이해

정적언어(C, C++, C#, Java)을 다뤄보신 분이라면 제네릭(Generic)에 대해 잘 알지는 못하더라도 한 번쯤은 들어봤을 것이다. 특히 자료구조 같이 구조체를 직접 만들어 사용할 때 많이 쓰이기도 하고

st-lab.tistory.com

 

Generics in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

Wildcards in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

1. Generic?

제네릭은 C++의 템플릿과 비슷한 개념이다.(같지는 않음)

제네릭을 사용하면 클래스를 여러가지 타입으로 만들어줄 수 있다.

쉽게 생각하면 일반적으로 사용하는 ArrayList같은 컬렉션을 생각하면 된다.

ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<String> list2 = new ArrayList<String>();
 
LinkedList<Double> list3 = new LinkedList<Double>():
LinkedList<Character> list4 = new LinkedList<Character>();

제네릭은 위 코드처럼 타입을 클래스 내부가 아닌 사용자가 지정하는 것을 의미한다.

 

물론, Object를 사용하면 Object는 모든 java class의 super class이기 때문에 비슷하게 구현이 가능하지만, 이는 타입 안정성을 제공하지 않는다.

반면에 제네릭은 타입 안정성을 제공한다.

 

2. Generic의 장점

  • 코드 재사용: 메서드/클래스/인터페이스를 한 번만 작성하면 원하는 모든 유형에 사용할 수 있다.
  • 유형 안전성: Generics는 런타임보다 컴파일 시간에 오류가 나타나도록 한다.

 

3. Generice의 일반적인 사용

타입 설명
<T> Type
<E> Element
<K> Key
<V> Value
<N> Number

 

4. Generic Class

 

Generic을 사용하면 아래처럼 매개변수 유형을 지정할 수 있다.(사용하는 시점에서)

// Java program to show working of user defined
// Generic classes
  
// We use < > to specify Parameter type
class Test<T> {
    // An object of type T is declared
    T obj;
    Test(T obj) { this.obj = obj; } // constructor
    public T getObject() { return this.obj; }
}
  
// Driver class to test above
class Main {
    public static void main(String[] args)
    {
        // instance of Integer type
        Test<Integer> iObj = new Test<Integer>(15);
        System.out.println(iObj.getObject());
  
        // instance of String type
        Test<String> sObj
            = new Test<String>("GeeksForGeeks");
        System.out.println(sObj.getObject());
    }
}
15 
GeeksForGeeks

 

또한, 여러 타입의 매개변수를 전달할 수도 있다.

// Java program to show multiple
// type parameters in Java Generics
  
// We use < > to specify Parameter type
class Test<T, U>
{
    T obj1;  // An object of type T
    U obj2;  // An object of type U
  
    // constructor
    Test(T obj1, U obj2)
    {
        this.obj1 = obj1;
        this.obj2 = obj2;
    }
  
    // To print objects of T and U
    public void print()
    {
        System.out.println(obj1);
        System.out.println(obj2);
    }
}
  
// Driver class to test above
class Main
{
    public static void main (String[] args)
    {
        Test <String, Integer> obj =
            new Test<String, Integer>("GfG", 15);
  
        obj.print();
    }
}
GfG 
15


5. Generic Method

제네릭 메서드에서는 전달된 인수 유형에 따라 다른 유형의 인수로 호출할 수 있다.

class Test {
    // A Generic method example
    static <T> void genericDisplay(T element)
    {
        System.out.println(element.getClass().getName()
                           + " = " + element);
    }
  
    // Driver method
    public static void main(String[] args)
    {
        // Calling generic method with Integer argument
        genericDisplay(11);
  
        // Calling generic method with String argument
        genericDisplay("GeeksForGeeks");
  
        // Calling generic method with double argument
        genericDisplay(1.0);
    }
}
java.lang.Integer = 11 
java.lang.String = GeeksForGeeks 
java.lang.Double = 1.0

 

6. 제한된 Generic

참조 타입의 범위를 제한하고 싶을 때 사용한다.

 

<K extends T>	// T와 T의 자손 타입만 가능 (K는 들어오는 타입으로 지정 됨)
<K super T>	// T와 T의 부모(조상) 타입만 가능 (K는 들어오는 타입으로 지정 됨)
 
<? extends T>	// T와 T의 자손 타입만 가능
<? super T>	// T와 T의 부모(조상) 타입만 가능

6-1. extends

extends는 상한 한계. 즉, 타입과 자손 타입들만 가능하다.

<T extends B>	// B와 C타입만 올 수 있음
<T extends E>	// E타입만 올 수 있음
<T extends A>	// A, B, C, D, E 타입이 올 수 있음
 
<? extends B>	// B와 C타입만 올 수 있음
<? extends E>	// E타입만 올 수 있음
<? extends A>	// A, B, C, D, E 타입이 올 수 있음

대표적인 예로는 Number를 사용할 때이다.

public class ClassName <K extends Number> { 
	... 
}
 
public class Main {
	public static void main(String[] args) {
 
		ClassName<Double> a1 = new ClassName<Double>();	// OK!
 
		ClassName<String> a2 = new ClassName<String>();	// error!
	}
}

 

6-2. super

super는 하한한계. 즉, 타입과 조상 타입들만 가능하다.

<K super B>	// B와 A타입만 올 수 있음
<K super E>	// E, D, A타입만 올 수 있음
<K super A>	// A타입만 올 수 있음
 
<? super B>	// B와 A타입만 올 수 있음
<? super E>	// E, D, A타입만 올 수 있음
<? super A>	// A타입만 올 수 있음

대표적으로는 해당 객체가 업캐스팅(Up Casting)이 될 필요가 있을 때 사용한다.

예로들어 '과일'이라는 클래스가 있고 이 클래스를 각각 상속받는 '사과'클래스와 '딸기'클래스가 있다고 가정해보자.

이 때 각각의 사과와 딸기는 종류가 다르지만, 둘 다 '과일'로 보고 자료를 조작해야 할 수도 있다. (예로들면 과일 목록을 뽑는다거나 등등..) 그럴 때 '사과'를 '과일'로 캐스팅 해야 하는데, 과일이 상위 타입이므로 업캐스팅을 해야한다. 이럴 때 쓸 수 있는 것이 바로 super라는 것이다.

반응형

+ Recent posts