[Java] 제네릭(Generic) 문법 정리: 클래스, 메서드, 제한까지

2025. 5. 23. 14:08·공부/☕Java

✅ 1. 제네릭이란?

public class Box<T> {
    private T item;

    public void set(T item) {
        this.item = item;
    }

    public T get() {
        return item;
    }
}

public class Main {
    Box<String> box = new Box<>();
    box.set("String"); // <String> 제네릭 이기 때문에 타입은 String
}
  • 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다.
  • 즉, 클래스, 인터페이스, 메소드를 정의할 때 타입 매개변수를 선언하고 자료형의 제한을 둠으로써 타입 안전성을 가진다.
  • 제네릭을 사용하면, 자바 프로그램의 재사용성을 높이고 오류를 줄일 수 있게 된다.
  • 다양한 형태를 받을 수 있는 클래스를 만들 때 사용을 하며, 형변환을 사용하지 않을 수 있다. ( 보통은 Object인데 사용x )

(1) 참고 사항

  • 제네릭을 사용한 클래스를 생성 할 때는 타입 파라미터를 명시해도되고 안해도 된다. 하지만, 하는게 일반적임.
  • 타입 파라미터는 기본자료형은 사용이 불가능하며, 참조자료형만 사용이 가능하다.
  • 타입 파라미터는 필드의 자료형, 메소드 반환형, 인자의 자료형으로 사용이 가능하다.
  • 자료형 매개변수 즉, 타입 매개변수를 가지는 클래스와 인터페이스를 제네릭 타입이라고 한다.
  • 타입 파라미터는 하나가 아닌 여러개도 가능하다. <T1, T2 ...>
  • 타입 파라미터의 이름은 관례적으로 E, K, V, N, T ... 을 사용 한다.

✅ 2. 제네릭 타입 객체 생성 방법

public class Main {
    Data<String> data = new Data<>();          // ✅ 타입 명시 + 다이아몬드 연산자 사용
    Data data = new Data();                   // ✅ raw type 사용 (비추천)
    Data<String> data = new Data<String>();   // ✅ 타입 전체 명시
}

 

(1) Data<String> data = new Data<>(); - 권장 되는 방식

  • 제네릭 타입을 명시하고, 우측은 다이아몬드 연산자<>를 사용해 타입 추론을 맡기는 방식이다.

(2) Data data = new Data(); - 비권장 방식

  • 제네릭 타입을 명시하지 않아서 컴파일러가 타입을 추론하지 못한다. 즉, Object로 간주되어서 들어가게 된다.
  • 쉽게말해, Data<Object> data = new Data<>(); 형식으로 들어간다는 의미이다.

(3) Data<String> data = new Data<String>();

  • 양쪽 모두 타입을 명시한 전통적인 제네릭 사용 방식으로, 코드가 길고 중복이 된다는 단점이 있다.

✅ 3. 제네릭 인터페이스

// 제네릭 인터페이스 정의
interface Printer<T> {
    void print(T item);
}

// 제네릭 인터페이스 구현 - String 타입 전용
class StringPrinter implements Printer<String> {
    public void print(String item) {
        System.out.println("문자열 출력: " + item);
    }
}

// 제네릭 인터페이스 구현 - Integer 타입 전용
class IntegerPrinter<T> implements Printer<Integer> {
    public void print(Integer item) {
        System.out.println("정수 출력: " + item);
    }
}

// 메인 클래스
public class Main {
    public static void main(String[] args) {
        Printer<String> stringPrinter = new StringPrinter();
        stringPrinter.print("안녕하세요");

        Printer<Integer> intPrinter = new IntegerPrinter<>();
        intPrinter.print(123);
    }
}
  • 제네릭 인터페이스를 만들게되고, 구현 클래스는 인터페이스 클래스 제네릭 타입을 명시해줘야 한다. 명시를 하게 되면, 구현하는 추상메서드의 타입은 명시한 타입으로 정의를 해야 된다. 안그러면 오류가 난다.

✅ 4. 제네릭 메소드

(1) 인스턴스 제네릭 메소드

public class Printer {
    public <T> void print(T data) {
        System.out.println(data);
    }
}
// 타입 추론 메서드 호출
public class Main {
    public static void main(String[] args) {
        Printer p = new Printer();
        p.print("Hello"); // 문자열
        p.print(1); // 정수
    }
}
// 타입매개변수 명시 메서드 호출
public class Main {
    public static void main(String[] args) {
        Printer p = new Printer();
        p.<String>print("Hello");
        p.<String>print(1); // 오류 : 매개변수 값 String 타입이 아님.
    }
}
  • 매개변수나 반환값의 타입을 메서드 호출 시점에 지정할 수 있도록 만든 메서드를 의미한다.
  • 쉽게말해, 호출 당하는 쪽 메서드의 <> 제네릭을 부여함으로써, 매개변수 및 반환값의 타입을 맞춰주는 방식이다.
  • 하나의 메소드 정의로 여러 유형의 데이터를 처리할 때 유용하다.
  • 메서드를 호출할 때 타입매개변수를 생략해도 매개변수 타입으로 추론해서 넣어준다.
  • 하지만, 타입매개변수를 넣을 수도 있는 형태이다.

(1) 클래스 제네릭 메소드 ( statck 제네릭 메소드)

public class Printer {
    public static <T> void print(T data) {
        System.out.println(data);
    }
}
// 타입 추론 메서드 호출
public class Main {
    public static void main(String[] args) {
        Printer.print("Hello"); // 문자열
        Printer.print(1); // 정수
    }
}
// 타입매개변수 명시 메서드 호출
public class Main {
    public static void main(String[] args) {
        Printer.<String>print("Hello");
        Printer.<String>print(1); // 오류 : 매개변수 값 String 타입이 아님.
    }
}
  • 위의 인스턴스 제네릭 메서드와 동일하게 타입매개변수를 넣거나 생략할 수 있다.
  • 일반 static 메서드에서 제네릭이 들어간 형태이다.

✅ 5. 제네릭 타입 제한

public class Data<T extends Number> {
    public void print(T data) {
        System.out.println(data); // T 자료형에 맞는 변수값 출력
    }
}
public class Main {
    public static void main(String[] args) {
        Data<Integer> data = new Data<>();
        data.print(123);
        Data<String> data = new Data<>(); // 컴파일 에러: String은 Number의 하위 클래스가 아님.
    }
}
  • 제네릭 클래스, 제네릭 인터페이스, 제네릭 메소드를 정의할 때 적용가능한 자료형에 제한을 두는 것을 의미한다.
  • 제네릭 매개변수로 자료형 타입의 제한을 두는 것이며, 서브 클래스인 경우에만 가능하게 제한을 둘 수 있다.

'공부 > ☕Java' 카테고리의 다른 글

[Java] java.lang 패키지 정리: Object, String, Math 클래스 총정리  (0) 2025.05.26
[Java] 자바 함수형 인터페이스와 람다식(Lambda Expression) 쉽게 배우기  (1) 2025.05.23
[Java] 익명 클래스(Anonymous Class)  (1) 2025.05.22
[Java] 다형성(polymorphism)  (1) 2025.05.22
[Java] 추상화 - 추상클래스, 추상메서드, 인터페이스  (0) 2025.05.20
'공부/☕Java' 카테고리의 다른 글
  • [Java] java.lang 패키지 정리: Object, String, Math 클래스 총정리
  • [Java] 자바 함수형 인터페이스와 람다식(Lambda Expression) 쉽게 배우기
  • [Java] 익명 클래스(Anonymous Class)
  • [Java] 다형성(polymorphism)
junbin2
junbin2
java.lang.NullPointerException
  • junbin2
    bin's Development Diary
    junbin2
  • 전체
    오늘
    어제
    • 전체보기 (233)
      • 방송통신대학교 (87)
        • ⚙️컴퓨터의 이해 (11)
        • 💻컴퓨터과학 개론 (15)
        • 🔢자료구조 (14)
        • 🧬알고리즘 (10)
        • ⚙️운영체제 (14)
        • 🕸️이산수학 (11)
        • 🌍유비쿼터스 컴퓨팅 (11)
        • 🖥️컴퓨터과학과 (1)
      • 공부 (72)
        • 📚백엔드 공부 (6)
        • ☕Java (23)
        • 🌳Spring (13)
        • ⚙️C (12)
        • ⚡Python (15)
        • JavaScript (1)
        • 🛢️Database (0)
        • Algorithm Problem Solving (2)
      • 네트워크 (7)
        • 📜HTTP (7)
      • 스파르타코딩클럽 (64)
      • 정보 (2)
      • 정리가 필요한 글 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    컴퓨터과학 개론
    유비쿼터스
    Java
    이산수학
    배열
    자바
    자료구조
    방통대
    그래프
    알고리즘
    spring
    Python
    운영체제
    방송통신대학교
    파이썬
    컴퓨터의 이해
    컴퓨터과학과
    C언어
    방송대
    함수
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
junbin2
[Java] 제네릭(Generic) 문법 정리: 클래스, 메서드, 제한까지
상단으로

티스토리툴바