Generic Type(제네릭 타입)이란?

  • 타입을 파라미터(parameter)로 가지는 클래스와 인터페이스
  • 선언 시 클래스 또는 인터페이스 이름 뒤에 "<매개변수 타입>"부호를 붙임
  • 클래스를 정의하면서 사용할 변수의 데이터타입을 명시하지결정하지 않은 상태로 냅두다 데이터타입을 실행(컴파일)할 때 매개변수로 받아서 데이터 타입을 결정한다 (데이터타입에 유연하면서도 안정성까지 제공)
  • 제네릭은 어떠한 데이터타입을 기반으로도 인스턴스 생성이 가능하도록 자료형에 일반적인 클래스를 정의하는 문법이다(재사용이 가능)
  • 제네릭은 클래스, 인터페이스, 메서드를 정의할 때 타입을 매개변수로 사용할 수 있도록 한다

✔ Generic(제네릭)의 장점은?

  • 불필요한 타입 변경을 없애준다 (타입 변환 제거)
  • 엄격한 타입 검사를 통해 안정성을 높여준다 (컴파일 시에 미리 타입을 체크해서 에러 방지)

 Generic(제네릭) 선언

public class 클래스명<T>{...} //<T>는 매개변수의 타입(parameter type)이라 한다.
public class Product<T, M>{...}
public interface 인터페이스명<T>{...}

 

  • 제네릭 클래스(generic class)에서는 타입을 변수로 표시한다. 이것은 매개변수의 타입라 한다.
  • 매개변수의 타입은 객체 생성 시에 프로그래머에 의하여 결정된다

 

매개변수타입 표기

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

- 일반적으로 대문자 알파벳 한 문자로 표현한다

실행 클래스에서 객체를 생성할 때 구체적인 타입을 지정해 주어야 한다

 

Product<String> product1=new Product<String>();    //문자열을 저장

Product<Interger> product2=new Product<Integer>();     //정수를 저장

 

Product<클래스명, String> product=new Product<클래스명, String>();     //클래스도 넣기 가능함

 

(클래스명<타입인자>참조변수=new 클래스명<타입인자>();)

 


Generic Type 예시

더보기

1) class Product

public class Product<T,M> { //제네릭 타입 선언
private T kind;
private M model;
public Product() {}
public Product(T kind, M model) {
this.kind=kind;
this.model=model;
}
public T getKind() {
return this.kind;
}
public M getModel() {
return this.model;
}
public void setKind(T kind) {
this.kind = kind;
}
public void setModel(M model) {
this.model = model;
}
@Override
public String toString() {
return "kind : " + kind.getClass().getSimpleName().toUpperCase() + ", model :" + model;
}
}

2) class Product

public class Car {
private String color;
public Car() {
}
public Car(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}

3) class Tv

public class Tv {
private int size;
public Tv(){ }
public Tv(int size){
this.size=size;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
@Override
public String toString(){
return "[size : "+size +"인치]";
}
}

3) class SmartPhone

public class SmartPhone {
private String company;
private String os;
public SmartPhone() {
}
public SmartPhone(String company, String os) {
this.company = company;
this.os = os;
}
@Override
public String toString() {
return " [" + company + ", " + os +"]";
}
}

4) 실행 class : ProductRun

public class ProductExample {
public static void main(String[] args) {
/* class Car */
Product<Car, String> product1 = new Product<Car, String>(); //제네릭타입
product1.setKind(new Car());
product1.getKind().setColor("RED");
product1.setModel("베뉴");
System.out.println(product1.toString() + " [color : " + product1.getKind().getColor() + "]");
/* class Tv */
/*Product<Tv, String> product2 = new Product<Tv, String>();
product2.setKind(new Tv(48));
product2.setModel("스마트 TV");*/
Product<Tv, String> product2 = new Product<Tv, String>(new Tv(48), "스마트 TV");
System.out.print(product2.toString() + " ");
System.out.println(product2.getKind().toString());
/* class SmartPhone */
/*Product<SmartPhone, String> product3 = new Product<SmartPhone, String>();
product3.setKind(new SmartPhone("삼성", "안드로이드"));
product3.setModel("갤럭시 Z 플립3");*/
Product<SmartPhone, String> product3 = new Product<SmartPhone, String>(new SmartPhone("삼성", "안드로이드"), "갤럭시 Z 플립3");
System.out.print(product3.toString());
System.out.println(product3.getKind().toString());
// product3.getKind() -> SmartPhone의 주솟값. toString() -> SmartPhone이 가진 toString()
}
}

 

✔ 한정된 타입매개변수 (bounded type parameter)

- 타입매개변수로 전달되는 타입의 종류를 제한하고 싶은 경우가 있다

  이런경우 한정된 타입매개변수를 쓴다

 

✔ 사용법 : 매개변수타입뒤에 extends나 super 을 쓴다

class MyMath<T extends Number>{ ... } //Declaring Class (클래스선언)
.
.
MyMath<Integer or Double> m = MyMath<Integer or Double>(); //Declaring Object (객체선언)
<매개변수타입 extends 부모 클래스명>

> 부모클래스를 상속받은 자식 객체들만 가능한다  

 

<매개변수타입 extends 인터페이스명>
// implements 키워드를 사용해서는 안됨

> 인터페이스로부터 구현 클래스 객체들만 가능하다

 

✔ 와일드카드

제네릭 타입을 매개변수타입이나 리턴타입으로 사용할 때

구체적인 타입 대신에 와일드카드로 명시할 수도 있다.

 

와일드카드 사용법

와일드카드는 ? 기호로 표현한다 ( ? 기호는 어떤 타입 매개변수도 지정할 수 있다는 의미

현재 객체의 매개변수타입과 같지않은 타입의 인자도 받을 수 있다

 

<? extends 부모 클래스>

: 매개변수타입을 대치하는구체적인 타입으로

부모 클래스이거나 부모클래스로부터 상속받은 하위 객체만 타입으로 지정 > ?

 

<? super 자식 클래스>

: 매개변수타입을 대치하는 구체적인 타입으로

자식 클래스이거 나 자식 클래스가 상속하는 부모 객체만 타입으로 지정 > ?

 


 

✔ 제네릭 메소드

매개변수 타입과 리턴 타입으로 매개변수타입을 갖는 메소드를 제네릭 메소드라고 한다 (정적메소드에 많이 씀

 

✔ 제네릭 메소드 선언

- 리턴 타입 앞에 <> 기호를 추가하고 매개변수타입 기술

- 매개변수타입을 리턴 타입과 매개변수로 사용

public < 매개변수타입, ... > 리턴타입 메서드명( 매개변수, ... ) { ... }
public class GenericMethod{
//배열의 마지막 원고를 반환하는 메소드
public static <T> T getLast(T[] array){
return array[array.length -1];
}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

'Language > Java' 카테고리의 다른 글

JAVA 기본 API  (0) 2022.02.28
컬렉션 (Collection)  (0) 2022.02.23
예외 (Exception Event)  (0) 2022.02.22
내부 클래스 (중첩 클래스)  (0) 2022.02.21
다형성 (Polymorphism)  (0) 2022.02.21