반응형
제네릭
- 클래스 선언시에는 결정하지 못한 필드 또는 매개변수 또는 메소드의 리턴타입을 객체가 생성시에 결정짓도록 하는 방법
- 타입변수는 래퍼클래스 사용
- 제네릭 클래스 사용시 생성 객체를 담는 변수에도 반드시 <> 기호를 사용하여 타입의 데이터타입을 결정해줘야 한다
생략시 Object 타입으로 받는다 - 원리 : 타입파라미터라고 하는 외부에서 타입을 전달받을 수 있는 타입변수 사용하여 객체 생성시 타입변수로 타입을 전달받아 객체 내부의 데이터타입을 결정짓는다
- 다이아몬드 문법 : 제네릭을 사용한 객체 생성시 왼쪽의 클래스 변수의 타입을 보고 오른쪽 타입을 예측할 수 있다면
타입값을 생략하는 문법을 의미(자바 8버전 이상부터 사용할 수 있다) - 제네릭 타입을 갖는 부모 클래스를 상속받는 경우 자식쪽에서 부모의 타입을 결정할 수 있다
- 자식 타입파라미터 값은 부모로 전달할 수 있다
1) A, B, Main01
public class A {
public Object field01;
}
public class B <A> {
private A field01;
public void setField01(A field01) {
this.field01 = field01;
}
public A getField01() {
return field01;
}
}
public class Main01 {
public static void main(String[] args) {
A a01 = new A();
a01.field01 = "Hi"; //String
A a02 = new A();
a02.field01 = 'H'; //Character
String f01 = (String)a01.field01; //강제형변환 필요
//String f02 = (String)a02.field01; //java.lang.ClassCastException 오류 발생
if(a02.field01 instanceof String) {
String f02 = (String)a02.field01;
}
B<String> b = new B<String>();
B<Character> bb = new B<Character>();
b.setField01("H");
String f = b.getField01();
bb.setField01('H');
System.out.println("프로그램 종료");
}
}
2) Box, GenericExample
타입파라미터로 T 사용
GenericExample 클래스에서 Box box1 생성할때 String으로 생성, Box box2 생성할때 Integer로 생성
public class Box<T> {
public T content;
}
public class GenericExample {
public static void main(String[] args) {
//Box<String> box1 = new Box<String>();
Box<String> box1 = new Box<>();
box1.content = "안녕하세요";
String str = box1.content;
System.out.println(str);
//Box<Integer> box2 = new Box<Integer>();
Box<Integer> box2 = new Box<>();
box2.content = 100; //int -> Integer로 자동 박싱
int value = box2.content;
System.out.println(value);
}
}
3) 제네릭 타입을 갖는 부모 클래스 상속
public class B <A> {
private A field01;
public void setField01(A field01) {
this.field01 = field01;
}
public A getField01() {
return field01;
}
}
public class Child01 extends B<String> {
public String field02;
public static void main(String[] args) {
Child01 child01 = new Child01();
child01.setField01("");
Child02 child02 = new Child02();
child02.setField01(100);
}
}
class Child02 extends B<Integer>{
}
4) 자식 클래스에서 생성할때 타입결정하도록 제네릭
자식 타입파라미터 값은 부모로 전달할 수 있다
public class B <A> {
private A field01;
public void setField01(A field01) {
this.field01 = field01;
}
public A getField01() {
return field01;
}
}
public class Child03<T> extends B<T> {
public static void main(String[] args) {
Child03<String> child03 = new Child03<String>();
child03.setField01("");
}
}
5) 아래의 코드를 보고 Container 제네릭 타입을 만들어보기
public static void main(String[] args) {
Container<String> container = new Container<String>();
container.set("홍길동");
String str = container.get();
Container<Integer> container2 = new Container<Integer>();
container2.set(6);
int value = container2.get();
}
만든 결과
public class Container<T> {
public T field;
public void set(T field) {
this.field = field;
}
public T get() {
return field;
}
public static void main(String[] args) {
Container<String> container = new Container<String>();
container.set("홍길동");
String str = container.get();
Container<Integer> container2 = new Container<Integer>();
container2.set(6);
int value = container2.get();
System.out.println("str :" + str + ", value :" + value);
}
}
실행결과)
str :홍길동, value :6 |
6) 해당 main을 실행했을때 실행결과가 밑처럼 나오도록 Sample01 제네릭 타입 만들기
100
안녕하세요
20
=> Sample01<Child01> sample01 = new Sample01<Child01>();
sample01.field01 = new Child01();
sample01.field01에 new Child01()을 생성하였기 때문에 Child01의 부모인 B에 있는 get, set을 사용하여
sample01.field01.setField01("100");
System.out.println(sample01.field01.getField01()); 가능하였다.
public static void main(String[] args) {
Sample01<Child01> sample01 = new Sample01<Child01>();
sample01.field01 = new Child01();
sample01.field01.setField01("100");
System.out.println(sample01.field01.getField01());
Sample01<String> sample02 = new Sample01<String>();
sample02.field01 = "안녕하세요";
System.out.println(sample02.field01);
Sample01<Integer> sample03 = new Sample01<Integer>();
sample03.field01 = 10;
System.out.println(sample03.field01 + 10);
}
만든 결과
public class B <A> {
private A field01;
public void setField01(A field01) {
this.field01 = field01;
}
public A getField01() {
return field01;
}
}
public class Child01 extends B<String> {
}
public class Sample01<T> {
public T field01;
public static void main(String[] args) {
Sample01<Child01> sample01 = new Sample01<Child01>();
sample01.field01 = new Child01();
sample01.field01.setField01("100");
System.out.println(sample01.field01.getField01());
Sample01<String> sample02 = new Sample01<String>();
sample02.field01 = "안녕하세요";
System.out.println(sample02.field01);
Sample01<Integer> sample03 = new Sample01<Integer>();
sample03.field01 = 10;
System.out.println(sample03.field01 + 10);
}
}
실행결과)
100 안녕하세요 20 |
7) 해당 main을 실행했을때 실행결과가 밑처럼 나오도록 Sample02 제네릭 타입 만들기
안녕하세요,
3.15
public static void main(String[] args) {
Sample02<String> s1 = new Sample02<String>();
s1.field = "안녕하세요,";
String resultStr = s1.getField();
System.out.println(resultStr);
Sample02<Double> s2 = new Sample02<Double>();
s2.field = 3.15;
Double resultDouble = s2.getField();
System.out.println(resultDouble);
}
만든 결과
public class Sample02<T> {
public T field;
public T getField() {
return field;
}
public static void main(String[] args) {
Sample02<String> s1 = new Sample02<String>();
s1.field = "안녕하세요,";
String resultStr = s1.getField();
System.out.println(resultStr);
Sample02<Double> s2 = new Sample02<Double>();
s2.field = 3.15;
Double resultDouble = s2.getField();
System.out.println(resultDouble);
}
}
실행결과)
안녕하세요, 3.15 |
반응형
'Java' 카테고리의 다른 글
[Java] 컬렉션 프레임워크 (0) | 2024.08.16 |
---|---|
[Java] 제네릭 타입 (0) | 2024.08.15 |
[Java] Date, SimpleDateFormat, Calendar (0) | 2024.08.13 |
[Java] toString(), StringBuilder, StringTokenizer, Math, Wrapper (0) | 2024.08.10 |
[Java] Object, equals(), hashCode() (0) | 2024.08.09 |