(시청일 : 20171014)





import java.io.Closeable;
import java.io.Serializable;
import java.util.*;
/*
public class Generics<T> { // class level type parameter
    static class Hello<T> {
    }
    <S, T> T print(S t){ // method level type parameter
        System.out.println(t.toString());
    }
    public <S> Generics(S s){
    }
    static void print(String value) {
        System.out.println(value);
    }
    public static void main(String[] args) {
    }
}
*/
/*
public class Generics {
    //bounded type parameter 관련 예시
    static <T extends List & Serializable & Comparable & Closeable> void print(T t){} // intersection type
    static <T extends Comparable<T>> long countGreaterThan(T[] arr, T elem) {
        return Arrays.stream(arr).filter(s -> s.compareTo(elem) > 0).count();
    }
    public static void main(String[] args) {
        Integer[] arr = new Integer[] {1,2,3,4,5,6,7};
        String[] arr2 = new String[] {"a","b","c","d","e"};
        System.out.println(countGreaterThan(arr2, "a"));
    }
}
*/
/*
public class Generics {
    public static void main(String[] args) {
        Integer i = 10;
        Number n = i;
        List<Integer> intList = new ArrayList<>();
        List<Number> numberList = intList;   // compile error!! type parameter는 상속 관계 없어서..
        ArrayList<Integer> arrList = new ArrayList<>();
        List<Integer> numberList2 = arrList;  // no problem. List는 ArrayList의 수퍼타입
    }
}
*/
/*
public class Generics {
    // type 추론 예시
    static class MyList<E, P> implements List<E>{
        @Override
        public int size() {
            return 0;
        }
        @Override
        public boolean isEmpty() {
            return false;
        }
        @Override
        public boolean contains(Object o) {
            return false;
        }
        @Override
        public Iterator<E> iterator() {
            return null;
        }
        @Override
        public Object[] toArray() {
            return new Object[0];
        }
        @Override
        public <T> T[] toArray(T[] a) {
            return null;
        }
        @Override
        public boolean add(E e) {
            return false;
        }
        @Override
        public boolean remove(Object o) {
            return false;
        }
        @Override
        public boolean containsAll(Collection<?> c) {
            return false;
        }
        @Override
        public boolean addAll(Collection<? extends E> c) {
            return false;
        }
        @Override
        public boolean addAll(int index, Collection<? extends E> c) {
            return false;
        }
        @Override
        public boolean removeAll(Collection<?> c) {
            return false;
        }
        @Override
        public boolean retainAll(Collection<?> c) {
            return false;
        }
        @Override
        public void clear() {
        }
        @Override
        public E get(int index) {
            return null;
        }
        @Override
        public E set(int index, E element) {
            return null;
        }
        @Override
        public void add(int index, E element) {
        }
        @Override
        public E remove(int index) {
            return null;
        }
        @Override
        public int indexOf(Object o) {
            return 0;
        }
        @Override
        public int lastIndexOf(Object o) {
            return 0;
        }
        @Override
        public ListIterator<E> listIterator() {
            return null;
        }
        @Override
        public ListIterator<E> listIterator(int index) {
            return null;
        }
        @Override
        public List<E> subList(int fromIndex, int toIndex) {
            return null;
        }
    };
    static <T> void method(T t, List<T> list){
    }
    public static void main(String[] args) {
        List<String> s1 = new MyList<String, Integer>(); // no problem
        List<String> s2 = new MyList<String, String>();  // no problem
        Generics.method(1, Arrays.asList(1,2,3)); // no problem
        Generics.<Integer>method(1, Arrays.asList(1,2,3)); // no problem
        List<String> str = new ArrayList<>(); // no problem
        List<String> c = Collections.<String>emptyList(); // no problem
    }
}
*/
public class Generics {
    // ?(와일드 카드)와 T(제네릭 타입)의 차이점 관련 예시
    static void printList(List<Object> list){
        list.forEach(s -> System.out.println(s));
    }
    static void printList2(List<?> list){
        list.forEach(s -> System.out.println(s));
    }
    static void print(List<? extends Object> list) {}
    static class A {}
    static class B extends A {}
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3);
        printList(list); // compile error!! List<Integer>는 List<object>의 서브타입이 아니라서..
        printList2(list); // no problem
        List<Integer> listInt = Arrays.asList(1,2,3);
        print(listInt); // no problem
        List<B> listB = new ArrayList<B>();
        List<A> listA = listB; // compile error!!
        List<? extends A> la = listB; // no problem
        List<? super B> l2 = listB; // no problem
        List<? super A> l3 = listB; // compile error!!
        la.add(new B()); // compile error!!
        la.add(null); // null만 가능
    }
}


+ Recent posts