Generic
- generic이란 데이터 타입을 일반화한다는 것을 의미한다
- 사용자가 외부에서 필요에 의해 데이터 타입을 지정한다
- Static 변수는 제네릭을 사용할 수 없다
Type
타입 | 설명 |
<T> | Type |
<E> | Element |
<K> | Key |
<V> | Value |
<N> | Number |
선언방법
package org.opentutorials.javatutorials.generic;
class Person<T>{
public T info;
}
public class GenericDemo {
public static void main(String[] args) {
Person<String> p1 = new Person<String>();
Person<StringBuilder> p2 = new Person<StringBuilder>();
}
}
출처: 생활코딩(https://opentutorials.org/course/1223/6237)
Person<T>와 publiv T info를 통해 각각의 데이터 타입을 T로 지정하였다
그 후, 인스턴스를 생성할 때
Person<String> p1 = new Person<String>();
Person<StringBuilder> p2 = new Person<StringBuilder>();를 통해 각각의 데이터 타입을 정의해주었다
제네릭화
ex)
package org.opentutorials.javatutorials.generic;
class StudentInfo{
public int grade;
StudentInfo(int grade){ this.grade = grade; }
}
class StudentPerson{
public StudentInfo info;
StudentPerson(StudentInfo info){ this.info = info; }
}
class EmployeeInfo{
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
}
class EmployeePerson{
public EmployeeInfo info;
EmployeePerson(EmployeeInfo info){ this.info = info; }
}
public class GenericDemo {
public static void main(String[] args) {
StudentInfo si = new StudentInfo(2);
StudentPerson sp = new StudentPerson(si);
System.out.println(sp.info.grade); // 2
EmployeeInfo ei = new EmployeeInfo(1);
EmployeePerson ep = new EmployeePerson(ei);
System.out.println(ep.info.rank); // 1
}
}
출처 : 생활코딩(https://opentutorials.org/course/1223/6237)
위 코드에서 studentPerson과 EmployeePerson은 사실상 같은 구조를 가지고 있기 때문에 중복을 제거해줄 수 있다
>중복을 없앤 코드
package org.opentutorials.javatutorials.generic;
class StudentInfo{
public int grade;
StudentInfo(int grade){ this.grade = grade; }
}
class EmployeeInfo{
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T>{
public T info;
Person(T info){ this.info = info; }
}
public class GenericDemo {
public static void main(String[] args) {
Person<EmployeeInfo> p1 = new Person<EmployeeInfo>(new EmployeeInfo(1));
EmployeeInfo ei1 = p1.info;
System.out.println(ei1.rank); // 성공
Person<String> p2 = new Person<String>("부장");
String ei2 = p2.info;
System.out.println(ei2.rank); // 컴파일 실패
}
}
출처 : 생활코딩(https://opentutorials.org/course/1223/6237)
p1을 생성하며 Person클래스의 타입을<EmployeeInfo>를 통해 지정해주었고
인자로 EmployeeInfo(1)을 넣어주었다
p2는 컴파일 오류가 발생한다. String 타입을 지정해주었는데, String타입의 필드가 없기 때문이다
기본 데이터 타입과 제네릭
ex)
package org.opentutorials.javatutorials.generic;
class EmployeeInfo{
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
public T info;
public S id;
Person(T info, S id){
this.info = info;
this.id = id;
}
}
public class GenericDemo {
public static void main(String[] args) {
EmployeeInfo e = new EmployeeInfo(1);
Integer i = new Integer(10);
Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
System.out.println(p1.id.intValue());
}
}
출처: 생활코딩(https://opentutorials.org/course/1223/6237)]
class Person<T, S>처럼 두개의 타입을 지정할 수 있다
제네릭은 참조 데이터 타입만 사용가능하고, int나 char같은 기본 데이터 타입은 사용이 불가능해서 Wrapper클래스를 사용해줘야한다
p1인스턴스를 생성하기 전에
Integer i = new Integer(10);
코드를 통해 p1인스턴스의 매개변수에 i를 넣어 사용할 수 있도록 하였다
메소드 Generic
- 제네릭 메소드는 static이 가능하다
ex)
package org.opentutorials.javatutorials.generic;
class EmployeeInfo{
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
public T info;
public S id;
Person(T info, S id){
this.info = info;
this.id = id;
}
public <U> void printInfo(U info){
System.out.println(info);
}
}
public class GenericDemo {
public static void main(String[] args) {
EmployeeInfo e = new EmployeeInfo(1);
Integer i = new Integer(10);
Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
p1.<EmployeeInfo>printInfo(e);
p1.printInfo(e);
}
}
출처 : 생활코딩(https://opentutorials.org/course/1223/6237)
선언방식은
접근제어자 <제네릭타입> 반환타입 메소드이름(제네릭타입 파라미터)로 선언하면 된다
Generic의 제한
- extends를 통해 제네릭에 올 수 있는 타입을 제한한다
- 추상클래스를 상속하는 관계에서 뿐만 아니라 Interface를 implements하는 관계에서도 사용이 가능하다
ex)
package org.opentutorials.javatutorials.generic;
abstract class Info{
public abstract int getLevel();
}
class EmployeeInfo extends Info{
public int rank;
EmployeeInfo(int rank){ this.rank = rank; }
public int getLevel(){
return this.rank;
}
}
class Person<T extends Info>{
public T info;
Person(T info){ this.info = info; }
}
public class GenericDemo {
public static void main(String[] args) {
Person p1 = new Person(new EmployeeInfo(1));
Person<String> p2 = new Person<String>("부장"); //에러발생
///String은 info의 자식타입이 아니므로 오류가 발생한다
}
}
Person<T extends Info>를 통해 데이터 타입을 Info클래스 자신이나 그 자식으로 제한을 하고 있다
*본 게시글은 생활코딩<제네릭>을 공부하며 복습한 내용을 작성한 글입니다*
'JAVA' 카테고리의 다른 글
JAVA(2022.05.24)-java.time패키지 (0) | 2022.05.24 |
---|---|
JAVA(2022.05.23)-Date,Calendar (0) | 2022.05.23 |
JAVA(2022.05.21)- Collections Framework (0) | 2022.05.21 |
JAVA(2022.05.20)-java.util 패키지 (0) | 2022.05.20 |
JAVA(2022.05.19)-스트링 클래스 (0) | 2022.05.19 |