제네릭(Generic)은 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법을 의미한다.
class Person<T>{
public T info;
}
Person<String> p1 = new Person<String>();
Person<StringBuilder> p2 = new Person<StringBuilder>();
StudentPerson과 EmployeePerson는 같은 행위를 하고 있다.
공통 클래스를 만들면서 중복을 제거하게 됨으로써 유지보수와 코드의 가독성을 높일 수 있음
중복제거 전
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 rankl
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);
EmployePerson ep = new EmployeePerson(ei);
System.out.println(ep.info.rank) // 1
}
}
중복제거 후
StudentPerson와 EmployeePerson의 클래스를 Person으로 중복을 제거했지만 "부장"이라는 원하지 않은 String을 통해 타입이 안전하지 않은 상황
에 맞닥뜨리게 된다.
class Person{
public Object info;
Person(Object info){
this.info = info;
}
}
public class GenericDemo {
public static void main(String[] args){
Person p1 = new Person("부장");
EmployeeInfo ei = (EmployeeInfo)p1.info;
}
}
class Sample<T> {
private T anonyTypeData;
}
/**
*
* @param supplier java8의 함수형 인터페이스중 하나로 구현시점에 리턴값을 결정하며 타입이 정의된다.
* @param <T> test2메소드 호출시 전달받을 타입 파라미터로 supplier의 반환타입이자 test2의 반환타입으로 정의한다.
* @return
*/
public <T> T test2(Supplier<T> supplier){
System.out.println("supplier 인터페이스의 반환타입에 따라서 test2의 반환타입이 결졍된다.");
return supplier.get();
}