제네릭(Generic)

Ryu·2021년 4월 8일
0

java

목록 보기
7/7
post-thumbnail

Generic 타입이란?
'컴파일 단계'에서 '잘못된 타입 사용될 수 있는 문제'제거가능
컬렉션, 람다식, 스트림, NIO에서 널리사용
제네릭을 모르면 API 도큐먼트 해석 어려우므로 학습필요

Generic을 사용하는 ㅗ드의 이점
컴파일시 강한타입체크 가ㅏ능

실행시 타입 에러가 나는것 방지
컴파일 시에 미리 타입을 강하게 체크하여 에러 사전방지

List list = new ArrayList();
list.add("hello);
String str = (String)list.get(0);

의 코드를 타입변환하는 번거로움을 사전에 제거하기 위해

List<String>list=new ArrayList<String>();
list.add("hello");
String str=list.get(0);

제네릭 타입 사용 여부에 따른 비교
제네릭 타입을 사용하지 않은 경우
Object타ㅏ입 사용 -> 빈번한 타입비교 -> 비효율적인 코드

public class Box {

	private Object object;
	
	
	public Object getObject() {
		return object;
	}
	
	
	public void setObject(Object object) {
		this.object = object;
	}
public class BoxExample {

	public static void main(String[] args) {
		
		Box box=new Box();
		
		box.setObject("홍길동"); //String -> Object (자동타입변환)
		
		String name = (String)box.getObject(); //Object -> String (강제타입변환)
		
		box.setObject(new Apple()); //Apple -> Object (자동 타입변환)

		Apple apple = (Apple) box.getObject(); // Object -> Apple (강제 타입변환) 
		
	}
}

위의 코드를 제너릭타입를 사용하여

public class Box<T> {

//	private Object object;
	private T t;
	
//	public Object getObject() {
//		return object;
//	}
	public T getObject() {
		return t;
	}
	
//	public void setObject(Object object) {
//		this.object = object;
//	}
	public void setObject(T t) {
		this.t=t;
	}
public class BoxExample {

	public static void main(String[] args) {
		
		Box<String>box = new Box<String>();
		
		box.set("hello");
		
		String name = box.get();

  		Box<Integer> box1 = new Box<Integer>();
		box1.set(10);
		int value = box1.get();
  
	}
}

로 변환 가능

제네릭 타입은 두개 이상의 타입 파라미터 사용가능

package chap11;

public class Product<T,M> {

	private M kind;
	private M model;
	
	public M getKind() {
		return kind;
	}
	public void setKind(M kind) {
		this.kind = kind;
	}
	public M getModel() {
		return model;
	}
	public void setModel(M model) {
		this.model = model;
	}	
}

T와 M 두개 이상의 타입 파라미터를 사용하여

public class ProductEx {

	public static void main(String[] args) {
		
		Product<Tv,String> product1=new Product<Tv,String>();
		
		product1.setKind(new Tv());
		product1.setModel("스마트 TV");
		
		String tvModel=new String();
		System.out.println(tvModel);
		
		Product<Car,String> product2=new Product<Car,String>();
		
		product2.setKind(new Car());
		product2.setModel("전기Car");
		
		String carModel=new String();
		System.out.println(carModel);
	}
}

제네릭 메소드
매개변수 타입과 리턴 타입ㅂ으로 타입 파라미터를 갖는 메소드

제네릭 메소드 선언 방법
리턴 타입 앞에 <> 기호를 추가하고 타입 파라미터 기술
타입 파라미터를 리턴타입과 매개변수에 사용
public<타입파라미터,...> 리턴타입 메ㅔ소드명(매개변수,...){...}
publicBoxboxing(T t){...}

제네릭 메소드 호출하는 두가지 방법
리턴타입 변수 = <구체적인 타입>메소드명(매개값);
리턴타입 변수= 메소드명(매개값);

public class Util {

	public static<T>Box<T> boxing(T t){
		
		Box<T>box =new Box<T>();
		box.set(t);	
		
		return new Box();
	}
}

boxing을 제네릭 메소드로 구성하고

public class BoxingMethodEx {

	public static void main(String[] args) {
		
		Box<Integer>box1=Util.boxing(100);
		
		int intValue=box1.get();
		System.out.println(intValue);
		
		Box<String>box2=Util.boxing("홍길동");
		
		String strValue=box2.get();
		System.out.println(strValue);
	}
}

호출한다.

타입파라미터를 사용하면

class Box<T> {
	ArrayList<T> list = new ArrayList();
	void add(T item) {
		list.add(item);
	}
	T get(int i) {
		return list.get(i);
	}
	int size() {
		return list.size();
	}
	@Override
	public String toString() {
		return list.toString();
	}
}

다음과 같은 코드에서 타입파라미터 안에

class Fruit {
	@Override
	public String toString() {return "Fruit";}
}
class Apple extends Fruit {
	@Override
	public String toString() {return "Apple";}
}
class Grape extends Fruit {
	@Override
	public String toString() {return "Grape";}
}
class Toy {
	@Override
	public String toString() {return "Toy";}
}

각각 클래스를 안에 사용해도 자동으로 타입이 변환된다.

profile
쓴다.노트.하는동안.공부

0개의 댓글