티스토리 뷰

Academy

[210216]제네릭

VIRGIL ABLOH 2021. 2. 23. 01:33
반응형

- 학습 목표 달성 확인 목록

- [] 제네릭 문법을 사용할 때 이점을 설명할 수 있는가?

제네릭을 이용하면 다양한 타입의 객체를 모두 수용할수 있거나 또는 단일한 객체만 수용할수 있도록한다

만약 해당 객체가 아닌 다른 객체를 삽입하면 컴파일러가 필터링을 해줄수 있어 나중에 버그를 잡는데 유용하다.

 

- [] 제네릭 문법을 메서드에 적용할 수 있는가?

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
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함