Box라는 클래스를 선언하려고 하고, Box에 넣을 내용물로 content필드를 선언하려고 할 때, 타입을 무엇으로 해야할까?
public class Box{
public Object content;
}
box Box = new Box();
box.content = 모든 객체;
String content = (String)box.content;
Box를 생성하기 전에 개발자는 어떤 내용물을 저장할 지 알고 있다. 따라서 내용물의 타입을 미리 알려주면 Box는 content에 무엇이 대입되고 읽을 때 어떤 타입으로 제공할지 알게 됨
동적 바인딩
: 컴파일할 때 호출하는 메소드와 실행할 때 호출하는 메소드가 유동적으로 적용되는
- 실제로 멤버가 참조하는 주소 호출하는 방식(dynamic binding)
- 자바에선 항상 dynamic binding
- 객체(객체 생성, not 참조)의 메소드를 불러오려면 Casting 방법 사용
-> A instanceof B 가 true 일 경우 형 변환 가능
-> A가 B의 자식이거나 같은 경우 true
-> A의 참조 데이터 타입과 B의 부모가 같은 경우 false
: 결정되지 않은 타입을 파라미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능
public class Box<T>{
public T content;
}
// Box를 생성할 때 파라미터 T를 타입(String 등)으로 대체
Box<String> box = new Box<String>();
// 아래 코드도 가능
Box<String> box = new Box<>();
: 결정되지 않은 타입을 파라미터로 가지는 클래스/인터페이스
public class 클래스명<A, B> { }
public interface 인터페이스명<A, B> { }
public interface Rentable<T> {
P rent();
}
// Home class
public class Home {
public void turnOnLight() {
System.out.println("전등을 켭니다.");
}
}
// HomeAgency class
// 타입 파라미터를 Home 타입으로 대체했으므로 rent()메소드의 리턴 타입도 반드시 Home 타입이어야 함
public class HomeAgency implements Rentable<Home> {
@ Override
public Home rent() {
return new Home();
}
}
// Test
public class Test {
public static void main(String [] args) {
HomeAgency homeagency = new HomeAgency();
Home home = homeagency.rent();
home.turnOnLight();
}
}
-> 전등을 켭니다.
: 타입 파라미터를 가지고 있는 메소드
public <T, A ...> 리턴타입 메소드명 (매개변수,...) { }
// T타입을 내용물로 갖는 박스 객체 return
public <T> Box<T> boxing(T t) { }
1. Box<Integer> box1 = boxing(100);
2. Box<String> box2 = boxing("안녕하세요");
: 모든 타입으로 대체할 수 없고 특정 타입과 자식 또는 구현 관계에 있는 타입만 대체할 수 있는 타입 파라미터를 '제한된 타입 파라미터'라고 함
public <T extends 상위타입> 리턴타입 메소드(매개변수,...) { }
public <T extends Number> boolean compare(T t1, T t2) {
double v1 = t1.doubleValue(); // Number의 메소드
double v2 = t2.doubleValue();
return (v1 == v2);
}
public static void main(String[] args) {
boolean result1 = compare(10, 20);
boolean result2 = compare(4.5, 5.5);
: 제네릭 타입을 매개값/리턴타입 으로 사용할 때 타입 파라미터로 ?(와일드카드)를 사용할 수 있음

리턴타입 메소드명 (제네릭타입<? extends Student> 변수) { }
리턴타입 메소드명 (제네릭타입<? super Worker> 변수) { }
리턴타입 메소드명 (제네릭타입<?> 변수) { }