728x90
목차
1. 제네릭
■ 제네릭이란?
- 데이터의 타입을 일반화하는 것을 의미
- 내부 데이터 타입을 컴파일 시에 미리 지정하는 방법
- 데이터 타입을 미리 지정할 때 <>를 사용하여 지정
- 제네릭은 일반 자료형 사용 불가
- 객체의 타입 안정성을 높일 수 있음
- 제네릭의 타입 변수에 extends 키워드를 사용하여 특정 타입만을 사용하도록 제한 가능
■ 와일드카드
- 와일드카드란 이름에 제한을 두지 않음을 표현하는데 사용
- 물음표(?) 기호를 사용하여 와일드카드를 사용
- 와일드카드는 생성 시 자동으로 자료형을 가져옴
2. 예시
■ TestData
package j18_제네릭;
public class TestData<T, E> {
// int 자료형을 클래스화 시켜놓은 것 wrapper Class(래퍼 클래스)
// 제네릭은 일반 자료형을 쓸 수 없음
private T data1;
private E data2;
public TestData(T data1, E data2) {
this.data1 = data1;
this.data2 = data2;
}
@Override
public String toString() {
return "TestData [data1=" + data1 + ", data2=" + data2 + "]";
}
}
■ CMRespDto
package j18_제네릭;
// Commit Message Response Data Transfer Object
// 클라이언트가 서버에게 요청을 날리면 동일한 형식으로 응답해주는 응답 인터페이스
public class CMRespDto<T> {
private int code;
private String message;
private T data;
public CMRespDto(int code, String message, T data) {
super();
this.code = code;
this.message = message;
this.data = data;
}
@Override
public String toString() {
return "CMRespDto [code=" + code + ", message=" + message + ", data=" + data + "]";
}
}
■ Main
package j18_제네릭;
import j17_스태틱.싱글톤.C;
public class Main {
public static void main(String[] args) {
// ?는 생성 시 자동으로 자료형을 가져옴
// 가능한 자료형을 명시하는 것이 좋음
TestData<?, ?> td = new TestData<>("김준일", 30);
TestData<String, Integer> td = new TestData<String, Integer>("김준일", 30);
TestData<String, Double> td2 = new TestData<String, Double>("junil", 100.05); // 생성될 때 타입 결정
System.out.println(td);
System.out.println(td2);
// generic 안에 generic 타입의 자료형을 가져올 수 있음
// data에 td의 자료형인 TestData<String, Integer>를 넣음
CMRespDto<TestData<String, Integer>> cm =
new CMRespDto<TestData<String, Integer>>(200, "성공", td);
// td의 자료형을 자동으로 가져옴
// CMRespDto<TestData<?, ?>> cm =
// new CMRespDto<TestData<?, ?>>(200, "성공", td);
// CMRespDto<?> cm =
// new CMRespDto<>(200, "성공", td);
System.out.println(cm);
}
}
■ Main2
package j18_제네릭;
public class Main2 {
// 멤버 메소드는 생성해야지만 즉 객체 생성을 해야지 호출 가능
// extends 뒤의 자료형을 상속받은 경우만 와일드카드로 허용
// super 뒤의 자료형과 상속하는 클래스만 와일드카드로 허용
/*
* 예시
* Person을 상속받은 Student, Teacher
* <? extends Person> Person포함 하위 객체인 Student, Teacher가능
* <? super Student> Student포함 상위 객체인 Person 가능
*/
/*
* ? 와일드카드 제약
* extends 대상 객체 하위
* super 대상 객체 상위
*/
public CMRespDto<?> reponse(CMRespDto<?> cmRespDto) {
System.out.println("[응답데이터]");
System.out.println(cmRespDto);
return cmRespDto;
}
// <?> 와일드카드 : 어디에든 가져갈 수 있음, Object로 형변환 되었다고 생각
public static void main(String[] args) {
Main2 main = new Main2();
CMRespDto<String> hello =
new CMRespDto<String>(200, "성공", "안녕하세요");
CMRespDto<Integer> score =
new CMRespDto<Integer>(200, "성공", 85);
System.out.println("hello");
// Object로 형변환 되었다고 생각함 왜냐하면 <?>로 정의되어 있어 모호하기 때문
System.out.println(main.reponse(hello));
System.out.println("score");
System.out.println(main.reponse(score));
}
}