Type Here to Get Search Results !

Java Generic Parameter - 자바 제네릭 타입, 파라미터

이 글에서는 Java Generic에 대해서 살펴보도록 하겠습니다. 



1. Java Generic(자바 제네릭) 이란?

Java에서 Generic은 다양한 자료형을 지원하기 위한 기능입니다. Generic을 사용하면 클래스 또는 메소드에서 사용되는 자료형을 선언할 수 있으며, 이렇게 선언된 자료형은 클래스 또는 메소드가 실행될 때 구체적인 자료형으로 대체됩니다.


2. Java Generic(자바 제네릭)의 장점

Java Generic은 다음과 같은 이점을 제공합니다.

  1. 코드의 재사용성을 높입니다.
    • Generic을 사용하면 여러 자료형에 대해 동일한 코드를 작성할 수 있습니다. 예를 들어, LinkedList 클래스는 Generic을 사용하여 다양한 자료형을 저장할 수 있습니다.
  2. 코드의 가독성을 높입니다.
    • Generic을 사용하면 코드의 의도를 명확하게 표현할 수 있습니다. 예를 들어, ArrayList<String>은 문자열만을 저장하는 ArrayList임을 명시적으로 나타냅니다.
  3. 타입 안전성을 보장합니다.
    • Generic을 사용하면 컴파일 시간에 타입 체크를 수행하여 타입 안전성을 보장합니다. 이로 인해 런타임에 타입 에러가 발생할 가능성을 줄일 수 있습니다.

Generic은 클래스와 메소드에서 모두 사용할 수 있습니다. 클래스에서 Generic을 사용할 때는 클래스 이름 뒤에 <T>와 같은 형식으로 Generic 파라미터를 선언합니다. 메소드에서 Generic을 사용할 때는 메소드 이름 뒤에 <T>와 같은 형식으로 Generic 파라미터를 선언합니다.


3. Java Generic(자바 제네릭) 사용 예제

이번 단락에서는 Java Generic을 사용한 예를 가지고 설명을 해 보도록 하겠습니다. 

3.1 LinkedList<T> 예제 

예를 들어, 다음과 같은 간단한 LinkedList 클래스를 생각해보겠습니다.

public class LinkedList<T> {
    private Node<T> head;

    public void add(T data) {
        // ...
    }

    // ...
위의 LinkedList 클래스에서 T는 Generic 파라미터입니다. 이 클래스는 다양한 자료형을 저장할 수 있는 LinkedList를 제공합니다. add() 메소드는 T 타입의 데이터를 추가하는 메소드입니다. 메소드에서 Generic을 사용할 때는 파라미터와 리턴 타입 앞에도 Generic 파라미터를 선언할 수 있습니다.

3.2 Generic 타입을 이용한 추상화와 구현 예제

다음과 같은 인터페이스를 만들어보겠습니다.
public interface Stack<T> {
    void push(T element);
    T pop();
    T peek();
    boolean isEmpty();
}
위의 인터페이스에서 T는 Generic 파라미터입니다. Stack 인터페이스는 push(), pop(), peek(), isEmpty() 메소드를 제공합니다. T 타입의 element를 추가하는 push() 메소드와 T 타입의 element를 제거하고 반환하는 pop() 메소드, T 타입의 element를 반환하는 엿보기 peek() 메소드, 스택이 비어 있는지 확인하는 isEmpty() 메소드가 포함되어 있습니다.

이제 Stack 인터페이스를 구현하는 클래스를 만들어보겠습니다.

public class ArrayStack<T> implements Stack<T> {
    private T[] elements;
    private int top;

    public ArrayStack(int capacity) {
        elements = (T[]) new Object[capacity];
        top = -1;
    }

    public void push(T element) {
        elements[++top] = element;
    }

    public T pop() {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        T element = elements[top];
        elements[top--] = null;
        return element;
    }

    public T peek() {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return elements[top];
    }

    public boolean isEmpty() {
        return top == -1;
    }
}
위의 ArrayStack 클래스에서 T는 Generic 파라미터입니다. 이 클래스는 Stack 인터페이스를 구현하며, T 타입의 element를 저장하는 T[] 배열과 top 인덱스를 포함합니다. 즉, 스택을 Array를 이용하여 구현한 구현체 클래스입니다. 그래서, 이름을 ArrayStack으로 지었습니다.

push() 메소드는 T 타입의 element를 배열에 추가하고 top을 증가시킵니다. pop() 메소드는 배열에서 T 타입의 element를 제거하고 반환하며, peek() 메소드는 배열에서 T 타입의 element를 반환합니다. 하지만, toe을 바꾸지는 않습니다. isEmpty() 메소드는 스택이 비어 있는지 확인합니다.

이제 다음과 같은 예제 코드를 이용하여 Stack 인터페이스와 ArrayStack 클래스를 사용해보겠습니다.

Stack<Integer> stack = new ArrayStack<>(10);
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.pop()); // 3
System.out.println(stack.peek()); // 2
System.out.println(stack.pop()); // 2
System.out.println(stack.pop()); // 1
System.out.println(stack.isEmpty()); // true
      
위의 코드에서는 ArrayStack 클래스를 이용하여 Stack 인터페이스를 구현하고, push(), pop(), peek(), isEmpty() 메소드를 호출하여 스택을 조작합니다. Generic 타입을 이용하여 Stack 인터페이스와 ArrayStack 클래스를 추상화하고 구현함으로써, 다양한 타입의 스택을 사용할 수 있습니다.

3.3 제네릭 인터페이스를 구현하여 enum 타입을 구현한 예

다음은 제네릭 인터페이스를 이용하여 enum 타입을 구현한 예제입니다. 
public interface MyEnum<T> {
    T getValue();
}

public enum Color implements MyEnum<String> {
    RED("FF0000"),
    GREEN("00FF00"),
    BLUE("0000FF");
    
    private final String value;
    
    Color(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
}

위 예제에서는, MyEnum이라는 제네릭 인터페이스를 정의하였습니다. MyEnum 인터페이스는 getValue() 메소드를 선언하며, 이는 제네릭 타입 T를 반환합니다.

그리고 Color라는 enum 타입을 선언하였습니다. Color enum 타입은 MyEnum 인터페이스를 구현하였으며, 이를 위해 String 타입의 값을 각 항목에 대해 정의하였습니다.

Color enum 타입의 생성자는 String 타입의 값을 받으며, 이는 Color의 값(value)을 나타냅니다. Color enum 타입은 MyEnum 인터페이스의 getValue() 메소드를 구현하고 있으며, 이 메소드는 Color의 값을 반환합니다.

이렇게 제네릭 인터페이스를 구현하면, 다양한 타입의 값을 다루는 enum 타입을 만들 수 있습니다. 예를 들어, MyEnum 인터페이스의 타입 매개변수를 Integer로 바꾸어서, 값으로 숫자를 다루는 enum 타입을 만들 수도 있습니다.

이번 포스팅에서는 자바 제네릭을 이용하여 다양하게 활용할 수 있는 예제를 알아보았습니다. 
잘못된 점이나 문의 사항 있으시면 댓글 달아주시면 감사하겠습니다. 
긴 글 읽어 주셔서 감사합니다.