본문 바로가기

Programming/자바

자바 재정리 - 제네릭

: 타입을 파라미터로 가지는 클래스/인터페이스/메소드

 

타입 파라미터 => 코드 작성 시 구체적인 타입으로 대체되어 다양한 코드 생성시킴

 


cf. list collection => 크기 고정돼있지 않음

import java.util.ArrayList;
import java.util.List;  //List 인터페이스 => ArrayList, Vector, LinkedList..

public class ListEx1 {

    public static void main(String[] args) {
        //동적 배열 => 여러 타입 값들 넣을 수 있음
        //but 나중에 값 꺼낼 때 내부값 확인할 수 없어서 강제 캐스팅해야 함
        List list = new ArrayList(); //다형성 
        list.add("홍길동");
        list.add(10);
        list.add(2.6);
        list.add(false);

        //String str = list.get(0); //오류 => 인덱스 안 타입, 값 알 수 없어서 값 못 넘겨줌
        String str = (String)list.get(0); //강제 캐스팅
        int num = (int)list.get(1);  
        //매번 강제 캐스팅 하기 번거로움 -> 제네릭의 필요성

        for (int i=0;i<list.size();i++) {
            System.out.println(list.get(i)); 
        }
        
    }

}
//
홍길동
10
2.6
false
 
 

 

 

제네릭 타입 
  •  
import java.util.ArrayList;
import java.util.List;

public class GenericEx1 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<String>(); //List Collection에 제네릭 부여
        list.add("홍길동"); //String만 넣을 수 있음
        list.add("박찬호");  
        list.add("손흥민");
        list.add("이영희");
        list.remove(1); //삭제값 뒤에 있는 값들이 앞으로 옴
        list.add(1,"이영표"); //insert(중간 삽입) => 1번 자리 있던 숫자가 뒤로 밀림
        
        String name = list.get(1); //강제캐스팅 X
        System.out.println(name);
        
        for(String str:list) {
            System.out.println(str);  
        }
        
    }

}​

 

 

 

  •  
 
//비제네릭

public class Box {
    
    private Object object; //최상위 클래스 => 모든 객체 받을 수 있음

    public Object getObject() {
        return object;
    }

    public void setObject(Object object) {
        this.object = object;
    }
    
}


public class GenericEx2 {

    public static void main(String[] args) {
        /
        Box box = new Box();  //인스턴스 객체 생성

        box.setObject("홍길동");
        String name = (String) box.getObject();  //강제 형변환 필수
        
        box.setObject(new Apple());
        Apple apple = (Apple) box.getObject();  //강제 형변환 필수
        
    }
}



//제네릭

public class Box<T> {
    //객체 필드
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
    
}


public class GenericEx2 {

    public static void main(String[] args) {
        
        Box<String> box1= new Box<String>();
        box1.setT("김철수");
        String name = box1.getT();
        
        Box<Integer> box2 = new Box<Integer>();
        box2.setT(50);
        int age = box2.getT();  //강제 형변환 필요 없음
        
    }

}
 

 

 

 

멀티 타입 파라미터

ex. Class<K,V,..>, interface <K,V,..>

 

 

 

  •  
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;
    }
    
}


public class ProductEx1 {

    public static void main(String[] args) {
        
        Product<Tv, String> product1 = new Product<Tv, String>();
        product1.setKind(new Tv());
        product1.setModel("스마트TV");
        Tv tv = product1.getKind();
        String tvModel = product1.getModel();
        
        Product<Car, String> product2 = new Product<Car, String>();
        product2.setKind(new Car());
        product2.setModel("소나타");
        Car car = product2.getKind();
        String carModel = product2.getModel();
        
    }

}

 

 

 

 

제네릭 메소드

: 매개타입과 리턴타입으로 타입 파라미터를 갖는 메소드

 

 

 

  •  
public class Util {
    
    public static <T> Box<T> boxing(T t){ 
    //제네릭 타입 지정, Box클래스로 리턴함, boxing()의 t변수에 매개변수 대입
        Box<T> box = new Box<T>();
        box.setT(t);
        return box;
    }

}


public class UtilEx1 {

    public static void main(String[] args) {

        Box<Integer> box1 = Util.boxing(50);
        int value = box1.getT();
        
        Box<String> box2 = Util.boxing("김철수");
        String name = box2.getT();
        
    }

}

 

 

 

 

상속 및 구현
  • 클래스 상속
public class ChildProduct<T, M, C> extends Product<T, M> {  
//자식클래스에 타입파라미터 추가 가능

    private C company;

    public C getCompany() {
        return company;
    }

    public void setCompany(C company) {
        this.company = company;
    }
    
}


public class ChildProductEx1 {

    public static void main(String[] args) {

        ChildProduct<Tv, String, String> product1 = new ChildProduct<Tv, String, String>();
        product1.setKind(new Tv());
        product1.setModel("스마트TV");
        product1.setCompany("삼성");
        
        ChildProduct<Car, String, String> product2 = new ChildProduct<Car, String, String>();
        product2.setKind(new Car());
        product2.setModel("소나타");
        product2.setCompany("현대");
        
    }

}

 

 

 

 

  • 인터페이스 구현
public interface Storage<T> {

    //추상메소드
    public void add(T item, int index);
    public T get(int index);

}


//구현 클래스
public class StorageInter<T> implements Storage<T>{

    //배열타입 필드
    private T[] array;
        
    //생성자
    public StorageInter(int capacity) { //배열의 크기
        this.array = (T[])(new Object[capacity]);
        //T에 어떤 타입이 올지 모름 => 모든 타입 대입 가능한 Object클래스 사용
    }
    
    @Override
    public void add(T item, int index) {
        array[index]=item;
    }

    @Override
    public T get(int index) {
        return array[index];
    }

}


public class StorageInterEx1 {

    public static void main(String[] args) {
    
        Storage<String> storage1 = new StorageInter<String>(100);
        storage1.add("홍길동", 0);
        storage1.add("김철수", 1);
        String name = storage1.get(0);
        
        Storage<Tv> storage2 = new StorageInter<Tv>(50);
        storage2.add(new Tv(), 0);
        Tv tv = storage2.get(0);
        
    }

}
 

'Programming > 자바' 카테고리의 다른 글

자바 재정리 - 컬렉션 프레임워크  (0) 2022.09.09
자바 재정리 - 람다식  (0) 2022.09.08
자바 재정리 - 멀티 스레드  (0) 2022.09.07
자바 재정리 - API  (0) 2022.09.05
자바 재정리 - 예외 처리  (0) 2022.08.26