기타/프로그래밍 분류

JAVA - 제네릭

zelkova 2013. 10. 16. 10:57

제네릭은 List. Map같은 컬렉션에 저장하는 데이터 타입을 검증하기 위해 추가된 기능이다.


1. 제네릭은 제네릭 타입의 줄임말이다.

2. 제네릭은 컴파일 시 타입 검증을 위한 것이다.

3. 제네릭 타입 정보는 런타임 시에는 존재하지 않는다.

4. 제네릭 사용시 컬렉션에 추가되는 요소를 컴파일 시간에 확일할 수 있다.


제네릭 객체 생성

제네릭 객체를 생성하기 위해서는 다른 객체를 생성하는 방법과 거의 동일하다. 다만 생성되는 컬렉션 객체에 저장되는 데이터형을 형 매개변수로 지정할 수 있다는 것은 다르다.


ex)

class<Type parameter> variable name = new Class<Type Parameter>();


ex)

ArrayList<Integer> list = new ArrayList<integer>();

List<String> list = new ArrayList<String();

Vector<String> vec = new Vector<String>(10);


ex)ArrayList<E> 클래스

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{

public ArrayList(Collection<? extends E> c){

size = c.size();

int capacity = (int)Math.min((size * 110L) / 100, Integer.MAX_VALUE);

elementData = (E[]) c.toArray(new Object[capacity]);

}


public E get(int index){

RangeCheck(index);

return elementData[index];

}


public <T> T[] toArray(T[] a) {

if(a.length < size)

a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponetType(), size);

System.arraycopy(elementData, 0, a, 0, size);

if(a.length > size)

a[size] = null;

return a;

}

}


ex) Hashtable<K, V> 클래스

public class Hashtable<K, V> extends Dictionary<K, V> implements Map<K, V>, Cloneable, java.io.Serializable{

public Hashtable(Map<? extends K, ? extends V> t){

this(Math.max(2*t.size(), 11), 0.75f);

putAll(t);

}

}


제네릭 문자

T    전달되는 객체가 현 객체 내에서 데이터형(Type)을 의미할 때 사용

E    전달되는 객체가 현 객체 내에서 하나의 요소를 의미할 때 사용

K    전달되는 객체가 현 객체 내에서 Key값을 의미할 때 사용

V    전달되는 객체가 현 객체 내에서 value값을 의미할 때 사용


제네릭 선언하기

class Vehicle<T>{

T name = null;


vehicle(){

}


Vehicle(T name){

this.name = name;

}


public void setNamel(T name){

this.name = name;

}


public T getNamel{

return name;

}

public class Test{

public static void main(String[] args){

Vehicle<String> my = new new Vehicle<String>();

my.setNamel("FOR");


String s = my.getNamel();

Systme.out.println(s);

}

}


다형성 대입

다형성 대입은 상속 관계에 있는 데이터형들 중 하위 데이터형을 상위 데이터형에 대입할 수 있는 것을 말한다.

일반적으로STring 클래스의 상위 클래스는 Object이다. 그래서 아래코드처럼 String이나 Integer클래스를 상위 클래스에 대입할 수 있다. 이렇게 할 수 잇는 것을 다형성 대입 이라고 한다.

하지만 다형성 대입은 제네릭형 매개변수에는 적용되지 않는다.


ex)

Object o1 = new String()


Object o2 = new Integer("1");


제네릭 클래스에서는 형 매개변수의 상속관계가 제네릭 클래스의 상속 관계를 의미하지 않는다.


와일드 카드

1. "?"는 와일드카드를 의미함.

2. 형 매개변수(Type Parameter)자리에 선언

3. Vector<?>는 Vector<String>의 상위 데이터형(Super Type)

4. 와일드카드를 사용한 데이터형에서는 수정 메소드를 호출할 수 없다.


ex)

Vector<?> vec = new Vector<String>();

ArrayList<?> arry= new ArrayList<Integer>();

Vector vec2 = new Vector<String>();


제네릭 상속

1.제네릭에서는 extends를 사용해서 상위 데이터형을 지정할 수 있다.

2. extends 오른쪽에는 인터페이스와 클래스가 모두 올 수 있다.

3. extends는 오른쪽 데이터형에 따라서 확장을 뜻할 수도 있고 구현을 뜻할 수 도 있다.

4. 형 매개변수에는 와일드카드를 사용할 수 있다.

5. extends왼쪽에는 오른쪽에 선언된 데이터형의 하위 데이터형이 올 수 있다.

6.와일드카드와 extends를 함께 사용한 ㄷ제이터형에서 수정 메소드는 호출할 수 없다.

형 매개변수의 활용

ex)

public void setName(List<Vehicle> list){}

public void ssetName(List<? xtends vehicle> list) {]

public <T> void getName(T t){}

public <T extends String> void m1(ArrayList<T> a1, ArrayList<T> a2){

a1.add((T) "10");

}


EX)

pulbic void m2(ArrayList<? extends String> a1, ArrayList<? extends String>a2){

a1.add("test");


a1 = new ArrayList<String>();

a2 = new ArrayList<Object>();

String s = a2.get(0);

Object o = a2;

}


ex)

public class Collections{

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

Object[] a = list.toArray();

Arrays.sort(a);

ListIterator<T> i = list.listInterator();


for(int j = 0; j < a.length; j++){

i.next()

i.set((T) a[j]);

}

}

}


반응형