제네릭의 사용
제네릭 : 클래스 내부에서 사용할 데이터타입을 외부에서 지정
메소드의 매개변수와 유사하게 작동
내부
class Person<T>{
public T info;
}
외부
public class GenericDemo {
public static void main(String[] args) {
Person<String> p1 = new Person<String>(); //info=> String
Person<StringBuilder> p2 = new Person<StringBuilder>(); //info=> StringBuilder
}}
=> 클래스를 정의 할 때 info의 데이터 타입을 확정하지 않고, 인스턴스를 생성할 때 데이터 타입을 지정
제네릭 사용 이유
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
|
class StudentI{
public int grade;
StudentI(int grade){
this.grade=grade;
}
}
class EmployeeI{
public int rank;
EmployeeI(int rank){
this.rank=rank;
}
}
class People{
public Object info;
People(Object info){this.info=info;}
}
public class GenericDemo3 {
public static void main(String[] args) {
People p1 = new People("부장");1
}
}
|
cs |
=> 원래대로라면 메인메소드에서 EmployeeI나 StudentI의 인스턴스가 괄호 안에 들어와야 하나,
코드에서처럼 문자열 "부장"이 들어가도 에러 표시가 뜨지 않음 (Object가 허용한 것) => 심각한 문제
※

1
2
3
4
5
6
7
|
public class GenericDemo3 {
public static void main(String[] args) {
People p1 = new People("부장");
EmployeeI ei = (EmployeeI) p1.info;
//p1의 info는 Object라는 일반적인(=큰?) 데이터타입 가짐 -> EmployeeI로 형변환 필 }
}
|
cs |
//
Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class org.opentutorials.javatutorials.generic.EmployeeI (java.lang.String is in module java.base of loader 'bootstrap'; org.opentutorials.javatutorials.generic.EmployeeI is in unnamed module of loader 'app')
=> 작성 시 에러 뜨지 않지만 출력 시 에러 (컴파일 에러 X, 런타임 에러 O)
=> 타입이 안전하지 않음 (Type Safety)
∴ 제네릭 => 타입의 안정성 + 코드 중복 제거 위해 생성
제네릭의 특징 1 - 복수의 제네릭
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
class EmployeeI{
public int rank;
EmployeeI(int rank){
this.rank=rank;
}
}
class P <T, S>{ //쉼표 사용, 다른 이름
public T info;
public S id;
P(T info, S id){
this.info = info;
this.id = id;
}
}
public class GenericDemo3 {
public static void main(String[] args) {
P<EmployeeI,
} //에러 발생
}
|
cs |
- int 에러 해결
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
|
class EmployeeI{
public int rank;
EmployeeI(int rank){
this.rank=rank;
}
}
class P <T, S>{ //T, S에는 참조형 데이터타입만 올 수 있음 (int, char 등 기본 X)
public T info;
public S id;
P(T info, S id){
this.info = info;
this.id = id;
}
}
public class GenericDemo3 {
public static void main(String[] args) {
P<EmployeeI, Integer> p1 = new P<EmployeeI, Integer> (new EmployeeI(1), 1);
//래퍼(Wrapper) 클래스 사용 => 기본 데이터타입을 객체로 포장
System.out.println(p1.id);
}
}
|
cs |
제네릭의 특징 2 - 제네릭의 생략
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
|
class EmployeeI{
public int rank;
EmployeeI(int rank){this.rank=rank;}
}
class P <T, S>{
public T info;
public S id;
P(T info, S id){
this.info = info;
this.id = id;
}
public <U> void printInfo(U info) {
System.out.println(info);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
EmployeeI e = new EmployeeI(1);
Integer i = new Integer(10);
P p1 = new P(e,i); //윗줄에서 정의해서 데이터타입 생략 가능
}
}
|
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
|
class EmployeeI{
public int rank;
EmployeeI(int rank){this.rank=rank;}
}
class P <T, S>{
public T info;
public S id;
P(T info, S id){
this.info = info;
this.id = id;
}
public <U> void printInfo(U info) {
//printInfo 메소드 안에서 U로 지정된 데이터타입=> info 매개변수의 제너릭 데이터타입이 됨
System.out.println(info);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
EmployeeI e = new EmployeeI(1);
Integer i = new Integer(10);
P p1 = new P(e,i);
p1.printInfo(e); //여기서도 데이터타입 생략 가능
}
}
|
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
|
abstract class Info{
public abstract int getLevel();
}
class EI extends Info{
public int rank;
EI(int rank){this.rank=rank;}
public int getLevel() {
return this.rank;
}
}
class Per <T extends Info>{ //Info나 그 하위클래스만 들어오도록 제한
public T info;
Per(T info){
this.info = info;
}}
public class GenericDemo3 {
public static void main(String[] args) {
Per<EI> p1 = new Per<EI>(new EI(1));
Per
}
}
|
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
|
interface Info{
int getLevel();
}
class EI implements Info{
public int rank;
EI(int rank){this.rank=rank;}
public int getLevel() {
return this.rank;
}
}
class Per <T extends Info>{
public T info;
Per(T info){
this.info = info;
}}
public class GenericDemo3 {
public static void main(String[] args) {
Per<EI> p1 = new Per<EI>(new EI(1));
}
}
|
cs |
- 제한 없앨 때 발생하는 오류
1
2
3
4
5
6
7
8
|
class Per <T>{ // <T>=<T extends Object>
public T info;
Per(T info){
this.info = info;
info.
}}
|
cs |
※
'Programming > 자바' 카테고리의 다른 글
자바 재정리 - 참조 (0) | 2022.08.05 |
---|---|
생활코딩 자바 - Collections framework (0) | 2022.04.24 |
생활코딩 자바 - 참조 ? (0) | 2022.04.19 |
생활코딩 자바 - 상수2 - enum (0) | 2022.04.18 |
생활코딩 자바 - Object 클래스 (0) | 2022.04.18 |