반응형
- 제네릭
/** Generic 사용 안 할 시 **/
//public class Box {
//
// private Object t;
// public Object get() {return t;}
// public void set(Object t) {this.t = t;}
//
//}
/** Generic 사용 할 시 **/
public class Box<T> {
private T t;
public T get() {return t;}
public void set(T t) {this.t = t;}
}
// 1. 실행시 타입 에러가 나는 것보다는 컴파일시에 미리 타입을 강하게 체크해 에러를 사전에 방지할 수 있다.
// 2. 타입 변환을 제거할 수 있다.
// → 이와 같은 방법으로 컬렉션프레임워크가 탄생하게 되었다.
Box.java
public class GenericBox {
public static void main(String[] args) {
/** Generic 사용 안 할 시 **/
// Box box = new Box();
// box.set("Apple");
// String boxContent = (String) box.get();
//
// Box boxInteger = new Box();
// boxInteger.set(10);
// int boxContentInteger = (int) boxInteger.get();
/** Generic 사용 할 시 **/
Box<String> box = new Box();
box.set("Apple");
String boxContent = box.get();
Box<Integer> boxInteger = new Box();
boxInteger.set(10);
int boxContentInteger = boxInteger.get();
}
}
GenericBox.java
- 제네릭<멀티타입>
public class Product<T, M> {
private T kind;
private M model;
public void setModel(M model) {
this.model = model;
}
public void setKind(T kind) {
this.kind = kind;
}
public T getKind() {
return kind;
}
public M getModel() {
return model;
}
}
// Product<Tv, String> product = new Product<>(); 이와 같이 사용
Product.java 이렇게 멀티타입도 가능하다.
- 제네릭 메소드, 제네릭 <멀티타입> 메소드
public class Util {
// 기본 구조 : <T> 리턴타입 메소드명
// return type : box<T> 제너릭으로 선언된 Box Class
// 동작 : box 객체 선언 후 T 타입의 값을 box에 넣는다.
public <T> Box<T> boxing(T t){
Box<T> box = new Box<T>();
box.set(t);
return box;
}
// 멀티타입 제너릭 메소드 (두 객체의 키와 값을 비교하기)
public <Key,Value> boolean compare(Pair<Key,Value> p1, Pair<Key,Value> p2) {
boolean isSameKey = p1.getKey().equals(p2.getKey());
boolean isSameValue = p1.getValue().equals(p2.getValue());
boolean isSame = (isSameKey && isSameValue) ? true : false;
System.out.println("isSame ? : " + isSame);
return isSame;
}
}
Util.java
/** Generic 사용 할 시 **/
public class Box<T> {
private T t;
public T get() {return t;}
public void set(T t) {this.t = t;}
}
Box.java
import java.util.HashMap;
public class GenericMethod {
public static void main(String[] args) {
/** 제너릭 메소드 **/
Util util = new Util();
Box<Integer> box = util.<Integer>boxing(100);
int intValue = box.get();
System.out.println(intValue);
Box<String> box1 = util.<String>boxing("홍길동");
String intValue1 = box1.get();
System.out.println(intValue1);
/** 멀티타입 제너릭 메소드 **/
// 어디서 많이 본듯한 형태 → 컬렉션프레임워크 hashMap
Pair<Integer,Integer> pair = new Pair<>(100,200);
Pair<Integer,Integer> pair1 = new Pair<>(100,200);
System.out.println(util.compare(pair, pair1));
HashMap<String, String> at = new HashMap<>();
}
}
GenericMethod.java
- 제네릭 상속
public class Util {
// Number로 구현된 클래스만 사용 가능 int, double 등...
// Number에서 상속받은 메소드 사용 가능
// return type : int
public static <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
return (int) (v1 + v2);
}
}
Util.java
- 와일드카드
public class WileCard {
public static void registerCourse(Course<?> course) {
}
public static void registerCourseStudent(Course<? extends Student> course) {
}
public static void registerCourseWorker(Course<? super Student> course) {
}
public static void main(String[] args) {
/** 모든 클래스 사용 가능 **/
registerCourse(new Course<Person>("일반인 과정", 5));
registerCourse(new Course<Student>("학생", 5));
registerCourse(new Course<Worker>("근로자", 5));
registerCourse(new Course<HighStudent>("고등학생 과정", 5));
/** 하위 클래스만 사용 가능 **/
registerCourseStudent(new Course<Person>("일반인 과정", 5)); // Student 클래스 상속 안 받은 Person 클래스 이기 때문에 사용 불가
registerCourseStudent(new Course<Student>("학생", 5));
registerCourseStudent(new Course<Worker>("근로자", 5)); // Student 클래스 상속 안 받은 Worker 클래스 이기 때문에 사용 불가
registerCourseStudent(new Course<HighStudent>("고등학생 과정", 5));
/** 상위 클래스만 사용 가능 **/
registerCourseWorker(new Course<Person>("일반인 과정", 5));
registerCourseWorker(new Course<Student>("학생", 5));
registerCourseWorker(new Course<Worker>("근로자", 5)); // Student의 상위 클래스가 아니라 사용 불가
registerCourseWorker(new Course<HighStudent>("고등학생 과정", 5)); // Student의 상위 클래스가 아니라 사용 불가
}
}
WildCard.java
public class Course<T> {
private String name;
private T[] students;
public Course(String name, int capacity) {
this.name = name;
students = (T[]) (new Object[capacity]);
// T가 정해지지 않았는데 바로 사용 불가능 최상위 클래스 Object로 구현 한 다음 타입 변환 필요
}
public String getName() {
return name;
}
public T[] getStudents() {
return students;
}
}
Course.java
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person.java
public class Worker extends Person{
public Worker(String name) {
super(name);
}
}
Worker.java
public class Student extends Person{
public Student(String name) {
super(name);
}
}
Student.java
public class HighStudent extends Student{
public HighStudent(String name) {
super(name);
}
}
HightStudent.java
- 제네릭 상속
public class Product<T,M> {
private T kind;
private M model;
public T getKind() {
return kind;
}
public void setKind(T kind) {
this.kind = kind;
}
public M getModel() {
return model;
}
public void setModel(M model) {
this.model = model;
}
}
Product.java
// 자식 클래스는 무조건 부모 클래스의 제너릭 타입 이상을 가져야한다. (K, V 반드시 포함)
public class ChildProduct<K,V,C> extends Product<K, V> {
}
ChildProduct.java
public class ExtendsGeneric {
public static void main(String[] args) {
ChildProduct<String, String, Integer> childProduct = new ChildProduct<>();
}
}
ExtendsGeneric.java
반응형
'[Java] > [Java]' 카테고리의 다른 글
[Java] 자바 멀티스레드 [Multi-Thread] 스레드 그룹 (0) | 2022.09.23 |
---|---|
[Java] 자바 멀티스레드 [Multi-Thread] Runnable vs Thread (0) | 2022.09.22 |
[Java] 자바 InputStream, OutputStrema, Writer, Reader (0) | 2022.09.12 |
[Java] 자바 메모리 구조, String vs StringBuilder vs StringBuffer, 메모리 주소(힙 메모리 누수 팁), GC(가비지 컬렉터) (0) | 2022.08.21 |
[Java] 자바 List vs ArrayList (0) | 2022.08.02 |