티스토리 뷰
- 학습 목표 달성 확인 목록
- [] 제네릭 문법을 사용할 때 이점을 설명할 수 있는가?
제네릭을 이용하면 다양한 타입의 객체를 모두 수용할수 있거나 또는 단일한 객체만 수용할수 있도록한다
만약 해당 객체가 아닌 다른 객체를 삽입하면 컴파일러가 필터링을 해줄수 있어 나중에 버그를 잡는데 유용하다.
- [] 제네릭 문법을 메서드에 적용할 수 있는가?
public class Member {
String name;
int age;
public Member(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class G {
static <Object> Object echo(Object obj) {
return obj;
}
public static void main(String[] args) {
String obj1 = echo(new String("Java"));
Date obj2 = echo(new Date());
Calendar obj3 = echo(Calendar.getInstance());
File obj4 = echo(new File("ok"));
Integer obj5 = echo(Integer.valueOf(100));
System.out.println(obj1);
System.out.println(obj2);
System.out.println(obj3);
System.out.println(obj4);
System.out.println(obj5);
}
}
//결과
Java
Tue Feb 23 00:45:59 KST 2021
java.util.GregorianCalendar[time=1614008759309,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Seoul",offset=32400000,dstSavings=0,useDaylight=false,transitions=30,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2021,MONTH=1,WEEK_OF_YEAR=9,WEEK_OF_MONTH=4,DAY_OF_MONTH=23,DAY_OF_YEAR=54,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=4,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=45,SECOND=59,MILLISECOND=309,ZONE_OFFSET=32400000,DST_OFFSET=0]
ok
100
- [] 제네릭 문법을 클래스에 적용할 수 있는가?
제네릭 적용 전
class MemberBox {
Member value;
public void setValue(Member value) {
this.value = value;
}
public Member getValue() {
return value;
}
}
class StringBox {
String value;
public void setValue(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
class IntegerBox {
Integer value;
public void setValue(Integer value) {
this.value = value;
}
public Integer getValue() {
return value;
}
}
public class Exam0210 {
public static void main(String[] args) {
MemberBox box1 = new MemberBox();
box1.setValue(new Member("오은석", 29));
Member m = box1.getValue();
System.out.println(m);
StringBox box2 = new StringBox();
box2.setValue("java");
String str = box2.value;
System.out.println(str);
IntegerBox box3 = new IntegerBox();
box3.setValue(100);
int i = box3.value;
System.out.println(i);
}
}
이렇게 객체를 저장하려면 각 객체의 타입 별로 Box 클래스를 생성해야 한다
문제는 이런 식으로 코딩을 하면 타입별로 만들어야 할 Box 클래스가 무한정으로 늘어난다
즉 같은 일을 하는 클래스임에도 불구하고 다루는 객체의 타입이 다르다는 이유만으로 여러개의 유사 클래스를 반복적으로 정의해야 하는 문제가 발생한다
이때 해결책으로 다양한 타입의 객체를 저장할 수 있도록 다형성의 다형적 변수 특징을 이용하여 값을 저장하는 인스턴스 변수를 모든 객체의 수퍼클래스인 Object 타입으로 정의한다.
제네릭 적용 후
public class Exam0230 {
static class Box<T> {
T value;//T라는 타입의 인스턴스 주소를 저장할 value
public T getValue() {//T타입의 객체를 리턴
return value;
}
public void setValue(T value) {//T타입 객체를 받을 value
this.value = value;
}
}
public static void main(String[] args) {
Box<Member> b1 = new Box<>();
b1.setValue(new Member("오은석", 29));
Member m = b1.getValue();
System.out.println(m);
Box<Integer> b2 = new Box<>();
b2.setValue(100);
Integer i = b2.getValue();
System.out.println(i);
Box<String> b3 = new Box<>();
b3.setValue(new String("jetBrain"));
String str = b3.getValue();
System.out.println(str);
}
}
//결과
Member{name='오은석', age=29}
100
jetBrain
제네릭을 사용하면 한 개의 클래스를 가지고 특정 타입 또는 여러 타입의 객체를 다룰 수 있는 전용 객체를 만들 수 있다.
그리고 따로 형변환을 할 필요가 없어진다.
- [] 타입 파라미터가 무엇인지 알고 있는가?
T-type
E-element
K-key
N-number
V-value
S,U,V 등등 두,세번째 이름으로 주로 사용한다.
- [] 제네릭 타입의 배열을 생성할 수 있는가?
public class Exam0510 {
// 제네릭 배열 생성하기
// 예1) 제네릭의 타입 파라미터로 레퍼런스 배열을 생성할 수 없다.
static <T> T[] create1() {
T[] arr;
// arr = new T[10]; // 컴파일 오류! new 명령어를 사용할 때 제네릭의 타입 파라미터를 사용할 수 없다.
return null;
}
// 예2) 견본 배열을 받아서 복제하는 방법을 사용한다.
static <T> T[] create2(T[] arr) {
// copyOf(original, newLength)
// => 원래 배열(original)과 같은 타입의 배열을 배열크기(newLength)에 맞춰 새로 생성한다.
return Arrays.copyOf(arr, 10);
}
// 예3) 배열의 타입 정보를 받아 생성하기
@SuppressWarnings("unchecked")
static <T> T[] create3(Class<?> type) {
return (T[]) Array.newInstance(type, 10);
}
// 예4) 견본 배열의 타입 정보를 가지고 배열을 생성하기
@SuppressWarnings("unchecked")
static <T> T[] create4(T[] arr) {
Class<?> arrayTypeInfo = arr.getClass(); // 예) String[]
System.out.println(arrayTypeInfo);
Class<?> arrayItemTypeInfo = arrayTypeInfo.getComponentType(); // 예) String
System.out.println(arrayItemTypeInfo);
return (T[]) Array.newInstance(arrayItemTypeInfo, 10);
}
public static void main(String[] args) {
// 제네릭을 사용하는 메서드를 이용하여 배열 만들기
// 파라미터로 빈 배열을 넘기면,
String[] strs = create2(new String[0]);
System.out.println(strs.length);
// 내부에서 생성할 배열 크기 보다 더 큰 배열을 파라미터로 넘긴다면?
// copyOf() 그래도 새 크기에 맞춰 새 배열을 생성한다.
String[] temp = new String[100];
String[] strs2 = create2(temp);
System.out.println(strs2.length);
System.out.println(temp == strs2);
// 생성할 배열의 타입 정보를 넘긴다.
String[] strs3 = create3(Member.class);
System.out.println(strs3.length);
// 배열을 넘기면 배열의 항목 타입을 알아내어 새 배열을 만든다.
String[] strs4 = create4(new String[0]);
System.out.println(strs4.length);
}
}
- [] 프로젝트에 제네릭을 적용할 수 있는가?
해당프로젝트는 제네릭을 포함하며 후추 배울 ArrayList도 포함시킨 상태이다.
'Academy' 카테고리의 다른 글
| [210218]Command Design Pattern (0) | 2021.02.24 |
|---|---|
| [210217]자바 API (0) | 2021.02.24 |
| [210215]인터페이스/추상클래스 (0) | 2021.02.16 |
| [210210]추상클래스와 인터페이스 (0) | 2021.02.12 |
| [210209]Iterator/추상클래스/인터페이스 (0) | 2021.02.11 |
