ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] 제네릭 (Generic)
    JAVA 2022. 5. 16. 23:32
    반응형

    제네릭이란? 

    Java 타입의 일종으로 이것을 사용하여 잘못된 타입이 입력될 수 있는 문제를 컴파일 과정에서 미리 제거할 수 있다.

     

    제네릭 타입을 통해 강한 타입체크를 하기 때문.

    불필요한 타입변환 과정을 줄여 성능의 향상을 기대할 수 있다.

     

    예시

    일반 코드
    
    List li = new ArrayList();
    list.add("hello");
    String str = (String) li.get(0); // hello << 여기서 String으로의 타입변환 발생
    
    
    제네릭 사용시
    List li = new ArrayList();
    list.add("hello");
    String str = li.get(0); //이미 해당 리스트에 들어있는 값은 String이므로 타입변환이 필요하지 않다.

     

    클래스나 인터페이스에도 제네릭을 적용할 수 있다.

    // 이름 뒤에 타입을 표기
    public class ClassNm<T> {...}
    public interface IFNm<T> {...}

    사용 예시 1. 제네릭타입 클래스

    public class Box<T>{
    	private T t; //여기서 T는 클래스이름 뒤에 지정한 타입파라미터
        public T get() { return t; }
        public void set(T t) { this.t = t;}
    }
    
    
    // 객체생성 예시
    public class Example {
    	public static void main(String[] args){
      		Box<String> stringBox = new Box<String>(); //String type의 Box 객체
    		Box<Integer> intBox = new Box<Integer>(); //Integer type의 Box 객체
    		
    		stringBox.set("hello");
    		intBox.set(1234);
    		
    		String a = stringBox.get(); //hello
    		int b = intBox.get(); //1234
        }
    }

    위 예시를 통해 제네릭 타입을 이용해 클래스를 작성하면, 필요한 타입을 그때그때 넣어서 적용시켜 줄 수 있음을 알 수 있다.

     

    멀티타입도 가능하다.

    public class Product<T, M> {
    	//두가지 타입 (T, M)을 사용하는 클래스
    	private T kind;
    	private M model;
    	
    	public T getKind() {return this.kind;}
    	public M getModel() {return this.model;}
    	
    	public void setKind(T kind) {this.kind = kind;}
    	public void setModel(M model) {this.model = model;}
    }
    
    public class ProductExample {
    	public static void main(String[] args) {
    		Product<Tv, String> p1 = new Product<>();
    		
    		p1.setKind(new Tv());
    		p1.setModel("Samsung SmartTV");
    		
    		Tv tv = p1.getKind();
    		String tvModel = p1.getModel();
    		
    		Product<Car, String> p2 = new Product<>();
    		p2.setKind(new Car());
    		p2.setModel("SUV");
    		
    		Car car = p2.getKind();
    		String carModel = p2.getModel();
    	}
    }

    사용예시2. 제네릭 메서드 (  접근제한자 <type param> returnType methodNm(param) { ... }  )

    public class Util {
    		//접근제한자 <type param> returnType methodNm(param){...}
    		public static <T> Box<T> boxing(T t){
    			Box<T> box = new Box<>();
    			box.set(t);
    			return box;
    		}
    		
    		public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
    			boolean keyCompare = p1.getKey().equals(p2.getKey());
    			boolean valueCompare = p1.getValue().equals(p2.getValue());
    			return keyCompare && valueCompare;
    		}
            
            //제한된 타입 파라미터. 여기서는 숫자만 입력 가능하게 선언함
            public static <T extends Number> int compareNumber(T t1, T t2) {
    			double v1 = t1.doubleValue(); //doubleValue() : 입력 값의 두배로 반환
    			double v2 = t2.doubleValue();
    			
    			return Double.compare(v1, v2);
                //Double.compare(a, b) : return 1 (a > b) , 0 (a == b), -1 (a < b) 의 의미.
    		}
    }
    
    public class Pair<K, V> {
    	private K key;
    	private V value;
    	
    	public Pair(K key, V value) {
    		this.key = key;
    		this.value = value;
    	}
    
    	public K getKey() {
    		return key;
    	}
    
    	public void setKey(K key) {
    		this.key = key;
    	}
    
    	public V getValue() {
    		return value;
    	}
    
    	public void setValue(V value) {
    		this.value = value;
    	}
    }
    
    public class GenMethodExam {
    	public static void main(String[] args) {
    		Box<Integer> box1 = Util.boxing(1000);
    		Box<String> box2 = Util.boxing("String");
    		
    		int val1 = box1.get(); //1000
    		String val2 = box2.get(); //String
    		
    		
    		Pair<Integer, String> p1 = new Pair<>(1, "사과");
    		Pair<Integer, String> p2 = new Pair<>(1, "사과");
    		Pair<Integer, String> p3 = new Pair<>(2, "배");
    		
    		boolean result = Util.compare(p1, p2);
    		boolean result2 = Util.compare(p1, p3);
    		printResult(result); //두 객체는 같다.
    		printResult(result2); //두 객체는 다르다.
            
            
            //숫자비교
            int numResult = Util.compareNumber(10, 100); // -1 : v1 < v2
    		int numResult2 = Util.compareNumber(4.5, 3); // 1 : v1 > v2
    		int numResult3 = Util.compareNumber(1, 1); // 0 : v1 == v2
    		
    		System.out.println(numResult); // -1 (10 < 100)
            System.out.println(numResult2);// 1 (4.5 > 3)
    		System.out.println(numResult3); // 0 (1 == 1)
    	}
    	
    	public static void printResult(boolean value) {
    		if(value) { //keyCompare && valueComapre 결과
    			System.out.println("두 객체는 같다");
    		} else {System.out.println("두 객체는 다르다");}
    	}
    }

     

    와일드카드 아직 공부중.. 이후 추가 작성

    반응형

    댓글

Designed by Tistory.