TIL#17-1

DuBu·2023년 6월 30일
0

일본IT JAVA 연수과정

목록 보기
29/61
post-thumbnail

Generic

  • 데이터 타입을 파라미터화 시키는 것.
  • 타입을 컴파일 시점에 미리 정하고 들어간다.

다중 매개변수 기반 제네릭 클래스의 정의

  • 다중 매개변수 기반 제네릭 클래스는 두 개 이상의 타입 매개변수를 가지는 제네릭 클래스입니다.
class DDBoxDemo {
    public static void main(String[] args) {
        DBox<String, Integer> box1 = new DBox<>();
        box1.set("Apple", 25);

        DBox<String, Integer> box2 = new DBox<>();
        box2.set("Orange", 33);
        
        DDBox<DBox<String, Integer>, DBox<String, Integer>> ddbox = new DDBox<>();
        ddbox.set(box1, box2);

        System.out.println(ddbox);
    }
}

class DBox<T, U> {
    private T data1;
    private U data2;
    
    public void set(T data1, U data2) {
        this.data1 = data1;
        this.data2 = data2;
    }
    
    public String toString() {
        return "(" + data1 + ", " + data2 + ")";
    }
}

class DDBox<T, U> {
    private T box1;
    private U box2;
    
    public void set(T box1, U box2) {
        this.box1 = box1;
        this.box2 = box2;
    }
    
    public String toString() {
        return "DDBox: " + box1 + ", " + box2;
    }
}
  • 위의 예시 코드에서 Pair 클래스의 객체를 생성하고 키와 값을 가져오는 예시가 있습니다. Pair<String, Integer> 타입의 객체를 생성하여 키로 문자열을, 값으로 정수를 사용하였습니다. getKey()와 getValue() 메서드를 통해 해당 객체의 키와 값을 가져올 수 있습니다.

  • 이와 같이 다중 매개변수 기반 제네릭 클래스를 사용하면 클래스의 다양한 부분에 서로 다른 타입을 적용할 수 있습니다. 이는 코드의 재사용성과 타입 안정성을 높이는 데에 도움을 줍니다

제네릭 클래스의 타입 인자 제한하기

  • 제네릭 클래스의 타입 인자를 제한하는 방법으로는 타입 매개변수에 상속 관계를 지정하거나 인터페이스를 구현하도록 요구하는 방법이 있습니다. 이를 통해 특정한 타입들만을 인자로 받도록 제한할 수 있습니다.
class Box<T extends Number> {
    private T value;

    public Box(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }
}
public class GenericStrictArguments {
	public static void main (String[] args){
        Box<Integer> intBox = new Box<>(10);
        int value = intBox.getValue();  // 10을 가져옴

    	Box<String> strBox = new Box<>("문자열");  // 오류! String은 Number의 하위 클래스가 아님

    }
}
  • 위의 예시 코드에서 Box 클래스의 인스턴스를 생성하는 예시가 있습니다. Box<Integer> 타입의 객체를 생성하여 숫자 10을 포함시킬 수 있습니다. getValue() 메서드를 통해 해당 객체의 값을 가져올 수 있습니다.

그러나 Box<String> 타입의 객체를 생성하려고 하면 컴파일 오류가 발생합니다. 이는 String이 Number 클래스의 하위 클래스가 아니기 때문에 제네릭 타입 인자로 사용할 수 없기 때문입니다.

이와 같이 타입 인자를 제한함으로써, 제네릭 클래스를 특정한 타입들로 제한할 수 있습니다. 이는 코드의 타입 안정성을 높이고, 의도하지 않은 타입의 인자를 전달하여 발생할 수 있는 오류를 방지하는 데 도움을 줍니다.

제네릭 메소드

  • 제네릭 메서드는 메서드 선언 시에 타입 매개변수를 사용하여 여러 종류의 타입을 처리할 수 있는 메서드입니다. 이를 통해 메서드를 호출할 때마다 다른 타입을 사용할 수 있으며, 타입 안정성을 보장할 수 있습니다.
public class Utils {
    public static <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
}
public class GenericMethod {
	public static void main(String[] args){
      Integer[] intArray = { 1, 2, 3, 4, 5 };
      Utils.printArray(intArray);  // 1 2 3 4 5 출력

      String[] strArray = { "Hello", "World" };
      Utils.printArray(strArray);  // Hello World 출력
    }
}
  • 위의 예시 코드에서는 printArray 메서드를 호출하는 예시가 있습니다. Integer 배열과 String 배열을 인자로 전달하여 각각의 배열의 요소를 출력하였습니다. 이때, 메서드 호출 시에 사용되는 배열의 타입에 따라서 메서드가 제대로 동작하며, 컴파일러가 타입 체크를 수행하여 타입 안정성을 보장합니다.

  • 제네릭 메서드를 사용함으로써, 여러 종류의 타입을 처리할 수 있는 유연한 메서드를 구현할 수 있습니다. 이는 코드의 재사용성을 높이고, 타입 관련 오류를 최소화하는 데에 도움을 줍니다

SwapBox 예제

public class GenericClass {

	public static void main(String[] args) {
        Box<Integer> box1 = new Box<>();
       box1.set(99);   //오토 박싱 

       Box<Integer> box2 = new Box<>();
       box2.set(55);   //오토 박싱 

       System.out.println(box1.get() + " & " + box2.get());
       swapBox(box1, box2);
       System.out.println(box1.get() + " & " + box2.get());

	}

	private static <T extends Number> void swapBox(Box<T> box1, Box<T> box2) {
		T temp = box1.get();
		box1.set(box2.get());
		box2.set(temp);
	}

}

0개의 댓글