-
generic , 제네릭프로그래밍/JAVA 자바 2021. 7. 29.반응형
제네릭 : 서로 자료형이 달라도 처리할 수 있다.
package ex0728; public class Ex07_generic { public static void main(String[] args) { // 제네릭 : 서로 자료형이 달라도 처리할 수 있다. Test3<String> t1 = new Test3<String>(); t1.set("서울"); String s = t1.get(); System.out.println(s); Test3<Integer> t2 = new Test3<>(); t2.set(30); Integer n = t2.get(); System.out.println(n); } } // Generic class Test3<T> { private T t; public void set(T t) { this.t = t; } public T get() { System.out.println(t.getClass()); return t; } }
String 타입의 객체 t1을 생성하고, Integer 타입의 객체 t2를 생성한다.
각 객체에 타입에 맞는 값들을 넣어주고 set 메소드를 실행 해주면 그 값들이 타입과 값까지 변수t에 모두 설정이된다.
변수 t는 private 타입이니까 외부에서 값을 가져오려면 따로 get해주는 메소드를 만들고,
외부에서 새로 만든 메소드를 통해서 값을 가져와준다.
package ex0728; public class Ex08_generic { public static void main(String[] args) { // TODO Auto-generated method stub Test4<String, Integer> ob = new Test4<String, Integer>(); ob.set("자바", 100); ob.print(); } } class Test4<T, U> { private T t; private U u; public void set(T t, U u) { this.t = t; this.u = u; } public void print() { System.out.println("T : "+t.getClass().getName()+", "+t); System.out.println("U : "+u.getClass().getName()+", "+u); } }
이 경우는 제네릭을 2개를 정할 수 있게 해준 코드이다.
(타입을 2가지 정할 수 있다.)
객체 생성을 할때 첫번째 String 두번째 Integer를 준 모습을 볼 수 있다.
package ex0728; public class Ex09_generic { public static void main(String[] args) { // TODO Auto-generated method stub Test5<Integer> ob = new Test5<>(); ob.set(30); Integer i = ob.get(); System.out.println(i); } } // 제한된 타입 파라미터(bounded type parameter) // Number를 상속받은 클래스만 가능 class Test5<T extends Number> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } }
Number를 상속받은 제네릭
이 말은 곧 Number의 하위 클래스들만 이용가능 하다는 뜻
제네릭에 String을 넣으면 컴파일 오류가 나온다.
메소드에서 제네릭 만들기
package ex0728; public class Ex10_generic { public static void main(String[] args) { // TODO Auto-generated method stub Test6 t = new Test6(); t.print("java"); t.print(20); t.disp(30); //t.disp("java"); compile error } } // generic method 메소드에서 제네릭 만들기 class Test6 { public <U> void print(U u) { System.out.println(u.getClass().getName()+", "+u); } public <U extends Number> void disp(U u) { System.out.println(u.getClass().getName()+", "+u); } }
클래스에서 제네릭 타입 주는게아니라
메소드 만들때 제네릭 타입을 준다.
제네릭 인터페이스
package ex0728; public class Ex11_generic { public static void main(String[] args) { // TODO Auto-generated method stub TestImpl7<Integer> ob1 = new TestImpl7<>(); ob1.print(10); DemoImpl7 ob2 = new DemoImpl7(); ob2.print("java"); } } // 제네릭 인터페이스 interface Test7<T> { public void print(T t); } class TestImpl7<T> implements Test7<T> { @Override public void print(T t) { System.out.println(t); } } // 구현 클래스 -2 class DemoImpl7 implements Test7<String> { @Override public void print(String t) { System.out.println(t); } }
@SuppressWarnings("unchecked") // 부적절한 컴파일러의 경고를 제거하기 위해 사용
한마디로 경고 무시
package ex0729; public class Ex01 { public static void main(String[] args) { // TODO Auto-generated method stub Test1<Integer> t = new Test1<>(); t.append(10); t.append(20); t.append(30); //t.append("asd"); // 컴파일 오류 Integer i = t.get(2); System.out.println(i); } } class Test1<E> { private Object[] data; private int count; public Test1() { data = new Object[10]; } public void append(E e) { if(count >= data.length) { // ArrayIndexOutOfBoundsException = unchecked 예외/ 배열의 첨자가 초과한 경우 발생 throw new ArrayIndexOutOfBoundsException("요소의 개수를 초과 했습니다."); } data[count++] = e; } @SuppressWarnings("unchecked") // 부적절한 컴파일러의 경고를 제거하기 위해 사용 //경고 무시 public E get(int index) { if(index >= count) { throw new ArrayIndexOutOfBoundsException(index); } // 제네릭으로 cating 하면 경고가 발생한다.(제네릭은 캐스팅을 안하기 위해서 사용하는건데 이 경우에는 어쩔 수 없다.) 경고 무시를 해주자 return (E)data[index]; //다운 캐스팅 해줘야함 } public int getCount() { return count; } }
제네릭 배열
package ex0729; public class Ex03 { public static void main(String[] args) { // TODO Auto-generated method stub Test3<Integer> t = new Test3<>(); Integer[] i = {10,20,30}; t.set(i); Integer[] i2 = t.get(); System.out.println(i2[1]); } } class Test3<E> { private E[] data; public void set(E[] data) { this.data = data; } public E[] get() { return data; } }
package ex0729; public class Ex04 { public static void main(String[] args) { // TODO Auto-generated method stub Test4<Number> ob1 = new Test4<>(); ob1.set(new Integer(30)); // 타입 매개변수의 상속 관계는 성립 System.out.println(ob1.get()); //Integer i = ob1.get(); 컴파일 오류 //Number n = ob1.get(); //Integer i = (Integer)ob1.get(); Test4<Integer> ob2 = new Test4<>(); ob2.set(new Integer(30)); //Test4<Number> ob3 = ob2; // 컴파일 오류 제네릭은 업캐스팅이 불가능 } } class Test4<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } }
제네릭 - 와일드 카드
package ex0729; public class Ex05 { public static void main(String[] args) { // TODO Auto-generated method stub Test5<Integer> ob = new Test5<>(); ob.set(30); //Test5<Number> ob2 = ob; // 컴파일 오류. 상속 관계가 아님 //제네릭 - 와일드 카드 // ? : 모든 클래스나 인터페이스가 가능 //제네릭 타입에 의존적이지 않는 메소드 등을 호출할때 사용 Test5<?> ob2 = ob; ob2.print(); //ob2.set(new Integer(30)); 컴파일 오류 ?의 자료형 타입이 정해지지 않았는데 인티저의 값을 주는건 안됨 } } class Test5<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } public void print() { System.out.println(t); } }
<?> 아직 타입이 안정해졌다는 뜻
반응형'프로그래밍 > JAVA 자바' 카테고리의 다른 글
List / ArrayList / LinkedList / Set (0) 2021.08.01 List 인터페이스 (0) 2021.07.30 throw, throws / 예외 주기 (2) (0) 2021.07.29 throw / throws (0) 2021.07.29 예외 잡기 (try, catch, finally문) (0) 2021.07.29