이것이 자바다 11일차 - Chapter13 제네릭

Seo-Faper·2023년 1월 24일
0

이것이 자바다

목록 보기
13/20

제네릭이란?

결정되지 않은 타입을 파리미터로 처리하고 실제 사용할 때 파라미터를 구체적인 타입으로 대체시키는 기능이다.

package ch13.sec01;

public class Box<T> {
    public T content;
}

이렇게 클래스 옆에 <T> 를 통해 제네릭을 선언 할 수 있으며 객체 생성 시 정해지는 자료형에 의해 content가 담을 수 있는 종류가 정해지는 것이다.

package ch13.sec01;

public class GenericExample {
    public static void main(String[] args) {
        Box<String> box1 = new Box<>();
        box1.content = "안녕하세요.";
        String str = box1.content;
        System.out.println(str);

        Box<Integer> box2 = new Box<>();
        box2.content = 100;
        int value = box2.content;
        System.out.println(value);
    }
}

처음에는 <String>으로 선언했기 때문에 문자열이 담기고 그 다음은 Integer로 선언해 정수가 담기는 모습을 볼 수 있다.

제네릭 타입

제네릭 타입은 결정되지 않는 타입을 파라미터로 가지는 클래스와 인터페이스를 말한다.

package ch13.sec02;

public class Product <K,M>{
    private K kind;
    private M model;

    public K getKind() {return this.kind;}
    public M getModel(){return this.model;}
    public void setKind(K kind){this.kind = kind;}
    public void setModel(M model){this.model = model;}
}

이렇게 2개 이상의 파라미터는 쉼표로 구별한다.

제네릭 메소드

제네릭 메소드는 타입 파라미터를 가지고 있는 메소드를 말한다. 타입 파라미터가 메소드 선언부에 정의된다는 점에서 제네릭 타입과 차이가 있다.

public <A, B, ... > 리턴타입 메소드명(매개변수, ...) { ... }
package ch13.sec03.exam01;

public class Box<T> {
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
package ch13.sec03.exam01;

public class GenericExample {
    public static <T> Box<T> boxing(T t){
        Box<T> box = new Box<T>();
        box.setT(t);
        return box;
    }

    public static void main(String[] args) {
        Box<Integer> box1 = boxing(100);
        int intValue = box1.getT();
        System.out.println(intValue);

        Box<String> box2 = boxing("홍길동");
        String strValue = box2.getT();
        System.out.println(strValue);
    }
}

제한된 타입 파라미터

경우에 따라서는 타입 파라미터를 대처하는 구체적인 타입을 제한할 필요가 있다. 예를 들어 숫자를 연산ㄴ하는 제네릭 메소드는 대체 타입으로 Number 또는 자식 클래스 (Byte, Short, Integer, Long, Double)로 제한할 필요가 있다.

public <T extends 상위타입> 리턴타입 메소드(매개변수, ...) { ... }
package ch13.sec04;

public class GenericExample {
    public static <T extends Number> boolean compare(T t1, T t2){
        System.out.println("compare("+t1.getClass().getSimpleName()+", "+t2.getClass().getSimpleName()+")");

        double v1 = t1.doubleValue();
        double v2 = t2.doubleValue();
        return (v1 == v2);
    }

    public static void main(String[] args) {
        boolean result1 = compare(10,20);
        System.out.println(result1);

        boolean result2 = compare(4.5,4.5);
        System.out.println(result2);
    }
}

와일드카드 타입 파라미터

제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 타입 파라미터로 ?(와일드카드)를 사용할 수 있다. ?는 범위에 있는 모든 타입으로 대체할 수 있다는 표시이다.

package ch13.sec05;

public class Person {

}
class Worker extends Person{

}
class Student extends Person{

}
class HighStudent extends Student{

}
class MiddleStudent extends Student{

}
package ch13.sec05;

public class Applicant<T> {
    public T kind;
    public Applicant(T kind){
        this.kind = kind;
    }
}
package ch13.sec05;

public class Course {
    public static void registerCourse1(Applicant<?> applicant){
        System.out.println(applicant.kind.getClass().getSimpleName());
    }
    public static void registerCourse2(Applicant<? extends Student> applicant){
        System.out.println(applicant.kind.getClass().getSimpleName());
    }
    public static void registerCourse3(Applicant<? super  Worker> applicant){
        System.out.println(applicant.kind.getClass().getSimpleName());
    }
}

연습문제

4번, 가질 수 있지요.

public class Container<T>{
	private T t;
    public T get(){
   		return t;
    } 
    public void set(T t){
    	this.t = t;
    }
}

public class Container<K, V>{
	private K key;
    private V value;
    
    public K getKey(){
    	return this.key;
    }
    
    public V getValue(){
    	return this.value;
    }
    
    public void set(K key, V value){
    	this.key = key;
        this.vaule = value;
    }
}



public class Util{
	public static <K,V> V getValue(Pair<K, V> p, K l){
    	if(p.getKey() == k){
        	return p.getValue();
        }else{
        	return null;
        }
    }
}

profile
gotta go fast

0개의 댓글