본문 바로가기
java

Java | 제네릭

by 좋으네요 2023. 2. 6.
728x90

제네릭이란

결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능

public class Box {
 public ? content ;
}

 

  • Box클래스에서 결정되지 않은 content의 타입을 T라는 타입 파라미터로 정의 <T>는 T가 파라미터임을 뜻하는 기로호 타입이 필요한 자리에 T를 사용할 수 있음을 알려주는 역할을 한다.
  • Box클래스는 T를 content 필드의 사용으로 사용하였고 T가 무엇인지 모르겠지만 Box객체가 생성될 시점에 다른타입으로 대체된다는 것을 알고 있다.
public class Box <T> {
 public <T> content ;
}

 

  • Box의 내용물을 String으로 저장하고 싶다면 Box를 생설할 때 타입 파라미터 T 대신 String으로 대체하면 된다.
Box<Stirng>box = new Box<String>();
box.content = "안녕하세요.";
String content = box.content; //강제타입변환이 필요없어 "안녕하세요"를 바로 얻을 수 있음

 

  • Box의 내용물로 100을 저장하고 싶다면 Box를 생설할 때 타입 파라미터 T 대신 Integer로 대체하면 된다. Integer는 정수값을 표현하는 클래스 타입
Box<Integer>box = new Box<Integer>();
box.content = 100;
int content = box.content; //강제타입변환이 필요없어 100dmf 바로 얻을 수 있음

 

<T>에서 타입 파라미터로 쓰이는 T는 단지 이름일 뿐이기 때문에 A-Z 어떤 알파벳을 사용해도 좋다.

주의할 점은 타입 파라미터를 대체하는 타입은 클래스 및 인터페이스라는 것!!

Box<int>라고 작성하지 않은 이유는 기본타입은 타입 파라미터의 대체 타입 될 수 없기 때문이다.

 

  • 변수를 선언할 때와 동일한 타입으로 호출하고 싶다면 생성자 호출 시 생성자에는 타입명을 명시하지 않고 < >만 붙일 수 있다.
Box<Stirng>box = new Box<String>(); -> Box<Stirng>box = new Box< >();
Box<Integer>box = new Box<Integer>(); -> Box<Integer>box = new Box< >();

 

제네릭타입이란

결정되지 않은 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.

  • 제네릭 타입은 선언부에 ‘ < >’ 부호가 붙고 그 사이에 타입 파라미터들이 위치한다.
  • 타입 파라미터는 변수명과 동일한 규칙에 따라 작성할 수 있지만 일반적으로 대문자 알파벳 한 글자로 표현
  • 외부에서 제네릭 타입을 사용하려면 타입 파라마미터에 구체적인 타입을 지정해야한다. 만약 지정하지 않으면 Object타입이 암묵적으로 사용된다.
public class 클래스명<A, B,     > {.....}
public interface 인터페이스명<A, B,     > {.....}
//제네릭 타입, 타입 파라미터로 K, M정의 
public class Product<K, M> { 

//필드, 타입 파라미터를 필드 타입으로 사용
 private K kind;
 private M model;

//메소드, 타입 파라미터를 리턴 타입과 매개변수 타입으로 사용
 public K getKind() {return this.kind;}
 public M getModel() {return thsi.model;}
 public void setKind(K kind) {this.kind = kind;}
 public void setModel(M model) {this.model = model;}
}

 

  • 타입 파라미터는 기본적으로 Object타입으로 간주되므로 Object가 가지고 있는 메소드를 호출할 수 있다.
  • Box의 내용물을 비교하기 위해 타입 파라미터로 Object의 equals()메소를 호출한다.
public class Box<T> {
 public T content;

//Box의 내용물이 같은지 비교(content필드값 비교)
	public boolean compare(Box<T> other) {
		boolean result = content.equals(other.content);
		return result;
	}
}

 

제네릭 메소드

타입 파라미터를 가지고 있는 메소드. 타입 파라미터가 메소드가 메소드 선언부에 정의된다는 점에서 제네릭 타입과 차이가 있다.

  • 리턴 타입 앞에 < > 기호를 추가하고 파라미터를 정의한 뒤 리턴 타입과 매개변수 타입에서 사용한다.
public <A, B, ...> 리턴타입 메소드명(매개변수, ...) {....}
// <A, B, ...> -> 타입 파라미터 정의

 

  • boxing( )메소드는 타입 파라미터로 <T>를 정의하고 매개변수 타입과 리턴 타입에서 T를 사용한다.
public <T> Box<T> boxing(T t) {...}

 

  • 타입 파라미터 T는 매개값이 어떤 타입이냐 따라 컴파일 과정에서 구체적인 타입으로 대체된다.
Box<Integer> box1 = boxing(100);
Box<String> box2 = boxing("안녕하세요");

 

 

제한된 타입 파라미터

모든 타입으로 대체할 수 없고 특정 타입과 자식 또는 구현 관계에 있는 타입만 대체할 수 있는 타입 파라미터를 제한된 타입 파라미터라고 한다.

  • 경우에 따라 타입 파라미터를 대체하는 구체적인 타입을 제한할 필요가 있다. 예) 숫자를 연산하는 제네릭 메소드는 대체 타입으로 Number 또는 자식 클래스(Byte, Short, Integer, Long, Double)로 제한할 필요가 있다.
  • 상위타입은 클래스뿐만 아니라 인터페이스도 가능하며 인터페이스라고해서 implements를 사용하지 않는다.
public <T extend 상위타입> 리턴타입 메소드(매개변수, ...) {...}

 

와일드카드 타입 파라미터

제네릭 타입을 매개값이나 리턴 타입을 사용할 때 타입 파라미터로 ?(와일드카드)를 사용할 수 있다. ?는 범위에 있는 모든 타입을 대체할 수 있다는 표시이다.

'java' 카테고리의 다른 글

Java | 람다식  (1) 2023.02.02
Java | 컬렉션 프레임워크  (0) 2023.02.02
[java] 중첩 클래스  (0) 2023.02.01