지네릭스 정리

이성준·2022년 7월 19일
0

JAVA

목록 보기
2/2

지네릭스

     ArrayList arrayList = new ArrayList();
        arrayList.add(1);
        arrayList.add(2);
        arrayList.add("3");

        Integer a = (Integer)arrayList.get(2);
        System.out.println(a);
    }

jdk 1.5 이전에는 지네릭스가 없어서 이런식으로 arraylist에 모든 객체를 넣을수가 있었다 근데 만약
숫자만 넣고 싶으면? 꺼낼때 형변환을 해준다. 컴파일러는 Object를 Integer객체를 형변환한다고 생각하기 때문에 문제가 없다 근데 3번째 원소는 String타입이라서 Integer로 형변환하면 ClassCastException이 터진다. 즉 런타임 에러가 터진다. 그래서 자바 개발자들은 이걸 막기위해 이 런타임에러를 컴파일에러로 끌고오는 지네릭스라는걸 만든다.

ArrayList<Integer> arr = new Arraylist<Integer>();

지네릭스를 쓰면 컴파일러에게 타입정보를 제공해준다. 그러면 컴파일러가 컴파일시점에 체크해줄수가 있다.
그러면 뭐가좋냐?
1. 타입을 하나만 넣을수있으니까 타입 안정성을 제공한다
2. 타입체크와 형변환을 생략하니까 코드가 간결해진다.

타입변수

class Box<T> {}

타입문자 T를 타입변수라고 하는데 객체생성할때에는 저기다 실제 타입을 지정해준다
참조변수랑 생성자의 대입된 타입은 일치해야된다.

ArrayList<Object> list = new ArrayList<Integer>(); -> 안됨

지네릭 클래스 간의 다형성은 성립

List<Object> list = new ArrayList<Object>(); ->

제네릭 타입 제한하기

class FruitBox<T extends A>{
ArrayList<T> list = new ArrayList<>();
        }

A 클래스의 자손만 대입이 가능하다. , 인터페이스인경우에도 extends 키워드 사용

static멤버에는 타입변수를 사용할수 없다 -> 타입변수의 대입은 인스턴스 별로 다르게 가능해야하는데 static은 대입된 타입의 종류에 관계없이 동일해야한다
new 연산자 뒤에는 T를 쓸수없다. -> 컴파일러가 무슨타입인지 알아야된다.

와일드 카드 <?>

하나의 참조변수로 대입된 타입이 다른 객체를 참조 가능하다

ArrayList<? extends Number> list = new ArrayList<Integer>(); -> IntegerNumbers의 자손이니 가능
 ArrayList<? super Number> list2 = new ArrayList<Object>();
ObjectNumber 조상이니 가능 

지네릭 메서드

메서드를 호출할 때 마다 타입을 대입한다 지네릭 클래스와 지네릭 메서드는 클래스 변수와 지역변수의 관계라
class에서 T만 받아도 메서드에서 하한이나 상한을 줄수가 있다.

public static <T extends Comparable<? super T>> void sort(List<T> list) {
        list.sort(null);
    }

매개변수로 받은 List를 정렬하긴하는데 근데 이 List는 Comparable을 구현한 요소여야된다.

제네릭의 형변환

형변환이 되긴하지만 원시타입이랑 제네릭이랑 섞어서 쓰지말자

ArrayList<String> arr1 = (ArrayList<String>)new ArrayList<Object>(); -> 안됨

다른 지네릭 타입끼리는 어떻게해도 형변환이 안된다.
하지만 와일드 카드가 사용된 지네릭 타입으로는 형변환이 가능하다

ArrayList<? extends Object> arr2 = new ArrayList<String>();  ->;

Object, 그리고 Object의 자손이 가능하니까 String은 무조건 된다.

0개의 댓글