java - 제네릭(Generic)

imjingu·2023년 8월 31일
0

개발공부

목록 보기
439/481

제네릭은 C++의 템플릿이 발전한 형태
C++과는 달리 제네릭 대신 Object를 사용하면 모든 데이터 타입을 사용할 수 있지만, 경우에 따라 형변환 해줘야 되서 제네릭을 선호

제네릭(Generic) : 일반화, 범용화 라는 의미로
클래스나 메서드에서 사용하는 필드나 매개변수의 자료형(클래스형)을 호출하는 쪽에서 지정하도록 하는 기능

package chapter20230831;

class ObjectData {
	private Object data; // 클래스의 데이터 타입이 Object라서 모든 데이터 타입이 사용 가능
	
	public Object getData() {
		return data;
	}
	
	public void setData(Object data) {
		this.data = data;
	}
}
public class Generic {

	public static void main(String[] args) {
		ObjectData stringCommonData = new ObjectData();
		ObjectData integerCommonData = new ObjectData();
		stringCommonData.setData("abc"); // 클래스의 데이터 타입이 Object라서 모든 데이터 타입이 사용 가능
		integerCommonData.setData(100);
		System.out.println("stringCommonData : " + stringCommonData.getData()); // stringCommonData : abc
		System.out.println("integerCommonData : " + integerCommonData.getData()); // integerCommonData : 100
	}

}

package chapter20230831;

	class CommonData<T> { // 일반적인 방식으로는 클래스에서 미리 데이터 타입을 지정해야 하지만 제네릭을 사용하면 호출하는 쪽에서 데이터 타입을
		private T data; //데이터 타입으로 T를 지정 Type의 약자 클래스 선언에서 <> 사이에 다른 문자를 넣어도 됨
		
		public T getData() {
			return data;
		}
		public void setData(T data) {
			this.data = data;
		}
	}
	public class Generic2 {

		public static void main(String[] args) {
			CommonData<String> stringCommonData = new CommonData<String>(); // 호출하는 쪽에서 타입을 지정
			CommonData<Integer> integerCommonData = new CommonData<>(); // 선언하면서 타입을 지정하면 생성자에는 타입을 생략가능
			stringCommonData.setData("abc");
			integerCommonData.setData(100);
			System.out.println("stringCommonData : " + stringCommonData.getData()); // stringCommonData : abc
			System.out.println("integerCommonData : " + integerCommonData.getData()); // integerCommonData : 100
		}

	}

GenericMethodTest
제네릭 타입 메서드 : 메서드에 타입 매개변수를 사용하여 선언한 것
매개변수로 사용하는 타입 매개변수를 반환값 앞에 선언

package chapter20230831;

class GenMethod {
	public <K, V> boolean compare(K fKey, V fValue, K sKey, V sValue) {
		if (fKey.equals(sKey) && fValue.equals(sValue)) {
			return true;
		}
		return false;
	}
}

public class Generic3 {

	public static void main(String[] args) {
		GenMethod genMethod = new GenMethod();
		
		// 메서드의 호출시에는 객체.<클래스형들>메서드이름<매개변수들> 형식으로 사용하는데
		// <클래스형들>은 생략가능 컴파일러가 매개변수로 필요한 타입을 추론
		boolean check = genMethod.<Integer, String>compare(1, "홍길동", 1, "홍길동");
		System.out.println("check : " + check); // true

	}

}

MultipleGenericTypeTest
제네릭 타입 클래스 : 클래스의 객체를 생성할 때 매개변수를 사용해 특정 타입을 전달하여 이를 기반으로 클래스의 객체가 생성 및 작동하도록 지원하는 것.
어떤 문자를 사용해도 되나 미리 지정된 타입이 있음. 가급적 타입에 맞게 문자를 사용하는 것이 가독성을 높임.
E : Element의 약자. 컬레션 프레임워크를 사용할 때 각 객체를 지칭하는 의미로 사용.
K : Key의 약자. 키와 값이라는 쌍으로 이루어진 형태에서 '키'의 의미로 사용.
V : Value의 약자. 키와 값이라는 쌍으로 이루어진 형태에서 '값'의 의미로 사용.
T : Type의 약자. 자료형이나 클래스의 의미로 사용.
제네릭에서는 기본 자료형(boolean, byte, char, int등)을 타입으로 사용할 수 없어서 여기서는 래퍼 Wrapper 클래스를 의미.
N : Number의 약자. 수치 계열의 의미로 사용. 여러 개를 사용할 때 각 타입 매개변수 뒤에 2, 3, 4등의 숫자를 붙여 사용.

package chapter20230831;

class IntString {
	private Integer key;
	private String value;
	
	public IntString(Integer key, String value) {
		this.key = key;
		this.value = value;
	}
	
	public void display() {
		System.out.println("key: " + key + ", value: " + value);
	}
}
class PairClass<K, V> { // 제네릭을 사용하지 않으면 위의 두개의 클래스를 따로 만들어야 하지만 제네릭을 사용하면 하나만 만들면 됨
	private K key;
	private V value;
	
	public PairClass(K key, V value) {
		this.key = key;
		this.value = value;
	}

	public void display() {
		System.out.println("key: " + key + ", value: " + value);
	}
}
public class MultipleGenericType {

	public static void main(String[] args) {
		PairClass<Integer, String> pairClass1 = new PairClass<>(1, "홍길동");
		PairClass<String, Double> pairClass2 = new PairClass<>("pi", 3.131592);
		pairClass1.display(); // key: 1, value: 홍길동
		pairClass2.display(); // key: pi, value: 3.131592
	}

}

0개의 댓글