[TIL] 제네릭
제네릭이란?
- 다양한 타입의 객체를 다루는 클래스나 인터페이스에서 사용할 데이터 타입을 인스턴스를 생성할 때 결정하는 것으로 JDK 5.0부터 지원
- 데이터 형에 대한 별도의 메소드나 멤버 변수를 구현할 필요 없이 미리 정의된 메소드 또는 멤버 변수에 서로 다른 자료 형으로 처리할 수 있다.
- 객체의 타입을 컴파일 할 때 체크하므로 객체 타입의 안정성을 높이고 불필요한 형 변환을 막을 수 있다.
장점
- 성능 저하를 유발하는 강제 캐스팅을 줄일 수 있다.
- 컴파일 할 때 타입 오류를 체크하므로 객체타입의 안정성을 높인다.
- 반복적인 코드를 줄일 수 있으며, 재사용성 증가로 유지보수가 편리하다.(오버로딩 줄일 수 있다.)
개요
타입 파라미터를 하나 이상 갖는 제너릭 타입의 클래스
클래스나 인터페이스를 선언할 때 타입을 지정하지 않고 인스턴스를 생성할 때 사용할 타입을 파라미터로 지정
제네릭 타입 파라미터
|
|
|
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
31
32
33
34
35
36
37
38
39
40
|
package ex0812;
public class Generic_Ex2 {
public static void main(String[] args) {
User20<String> obj = new User20<String>(); // JDK 5,6은 뒤에도 파라미터 넣어야함
User20<Integer> obj1 = new User20<>();//JDK 7부터는 생략 가능
obj.set("aaa");
obj1.set(123);
// class java.lang.String
// class java.lang.Integer
Integer ii = obj1.get();
//캐스팅 불필요
Test20 tt = new Test20();
tt.set(30);
// Integer ii2 = tt.get();// 캐스팅이 필요함
}
}
class User20<T>{
private T t;
public void set(T t) {
System.out.println(t.getClass().getName());
this.t=t;
}
public T get() {
return t;
}
}
class Test20{
private Object obj;
public void set(Object obj) {
this.obj = obj;
}
public Object get() {
return obj;
}
}
|
cs |
제한된 타입 파라미터
타입 파라미터로 전달되는 타입의 종류를 제한하기 위한 기능으로 extends 키워드를 사용한다.
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
|
package ex0812;
public class Generics_Ex5 {
public static void main(String[] args) {
User24<Integer> obj = new User24<>();
obj.set(10);
System.out.println(obj.get());
// User24<String> obj = new User24<>();
// 컴파일 오류 : 제한된 파라미터이기 때문
//number 하위 클래스만 가능하다.
}
}
//제한된 타입 파라미터
//extends를 통하여 제한할 클래스를 상속받는다.
class User24<T extends Number>{
private T t;
public void set (T t) {
this.t =t;
}
public T get() {
System.out.println(t.getClass().getName());
return t;
}
}
|
cs |
제네릭 메소드
- 타입 파라미터를 하나 이상 갖는 메소드를 말한다.
- 메소드를 선언할 때 타입을 지정하지 않고 메소드를 호출 할 때 명시적으로 타입을 지정하거나 메소드의 매개변수 값의 타입으로 지정한다.
- 선언 방법은 리턴 타입 앞에 <> 기호를 추가하고 <>안에 타입 파라미터를 기술 한 후 리턴 타입과 매개 변수 타입에서 타입 파라미터를 사용한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package ex0812;
public class GenericsMethod_Ex1 {
//제너릭 메소드
public static void main(String[] args) {
User23 ob = new User23();
ob.print("String");
ob.print(123);
}
}
class User23{
// 제네릭 메소드
public <U> void print(U u) {
System.out.println("U : "+u.getClass().getName());
}
}
|
cs |
제네릭의 와일드 카드
제네릭은 컴팡리 단계에서 타입 안정성을 위해 지원하므로 기본적으로 다형성을 갖지 않는다.
따라서 제네릭에 다형성을 갖도록 만들기 위해서 와일드 카드를 사용한다.
제네릭 타입을 매개값이나 리턴타입으로 사용할 때 구체적인 타입 대신 와일드카드 ? 를 사용할 수 있다.
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
|
package ex0812;
public class Generics_Ex7 {
public static void main(String[] args) {
User26<Integer> obj = new User26<>();
obj.set(10);
// User26<Number> obj2 = obj;// 업캐스팅은 안된다
User26<?> obj2 = obj; // 와일드 카드라고 한다.
// 제네릭의 타입이 결정되지 않은 상태
// obj2.set(20);// 타입이 결정되지 않앗으니 컴오류이다.
obj2.print();// 해당 print 메소드는 T에 의존적이지 않기때문에 가능하다.
System.out.println(obj2.get()); // 단순히 값을 가져오는건 가능하다.
}
}
class User26<T>{
private T t;
public void set(T t) {
this.t =t;
}
public T get() {
return t;
}
public void print() {
System.out.println("출력 : "+ t);
}
}
|
cs |
'Language > JAVA' 카테고리의 다른 글
[TIL] 컬렉션 - java.util.List<E> 인터페이스 & 구현 클래스 (0) | 2020.08.24 |
---|---|
[TIL] 컬렉션 프레임워크 (0) | 2020.08.14 |
[TIL] 예외처리 (3) | 2020.08.12 |
[TIL] 중첩 클래스 (0) | 2020.08.11 |
[TIL] 인터페이스 (0) | 2020.08.11 |
댓글