제너릭에서 와일드 카드

Choizz·2023년 2월 10일
0

Java

목록 보기
9/11

와일드 카드

이번 포스팅은 제너릭의 와일드 카드 문법에 대해서 알아보자.


우선 제너릭 클래스를 하나 만들었다.

public class TestWildcard<T> {

	T wildcard;

	public void setWildcard(T wildcard) {
		this.wildcard = wildcard;
	}

	public T getWildcard() {
		return wildcard;
	}
}
  • 밑 의 코드를 보면,
    • callTestWildcard 메서드에서 Integer를 가지는 TestWildcard 객체를 생성(1) 후 ,필드 값을 세팅해준다.(2)
      그 후 wildIntegerMethod에 그 객체를 파라미터로 넘겨준다.(3)
    • wildIntegerMethod는 Integer를 갖는 TestWildcard 객체를 받는다.(4)
public class WildcardRunner {

	public void callTestWildcard() {
		// 1
		TestWildcard<Integer> wildcard = new TestWildcard<>();
		// 2
		wildcard.setWildcard(123);
		//3
		wildIntegerMethod(wildcard);
	}

	//4
	public void wildIntegerMethod(TestWildcard<Integer> param) {
		Integer value = param.getWildcard();
	}

}

여기서 wildIntegerMethod의 파라미터로 TestWildcard<Integer>가 아닌 TestWildcard<String>을 사용해야 한다면 어떻게 해야할까??

와일드 카드(?) 사용

이런 경우 사용되는 것이 와일드 카드이다. 위 wildIntegerMethod에서 파라미터로 TestWildcard<?>를 사용하면 된다.

  • 메서드 내부에서는 해당 파라미터의 타입을 모르기 때문에 Object로 처리해야 한다.
  • 파라미터에서 ?로 명시한 것을 와일드 카드라고 한다.
public void wildIntegerMethod(TestWildcard<?> param){
	Object value=param.getWildcard();
	if(value instanceof String){
	    System.out.println(value);
	}
}

와일드 카드를 사용할 경우 주의사항

  • 와일드 카드는 메서드의 매개 변수로 사용하는 것이 좋다.
  • 밑의 코드(1)에서 처럼 객체를 생성하는데 사용하게 된다면 컴파일 에러가 발생한다.
  • ?로 설정을 했기 때문에 타입을 알 수 없고, 특정 타입을 지정할 수 없다.
public void callTestWildcard() {
	//1
	TestWildcard<?> wildcard = new TestWildcard<>();
	wildcard.setWildcard(123);
	wildIntegerMethod(wildcard);
}

와일드카드에서 extend 사용

  • 와일드카드에 extend를 사용함으로써 객체의 타입을 제한할 수 있다.
  • 먼저 Fruit 클래스를 만들고 이 클래스를 상속하는 Apple 클래스를 만든다.
public class Fruit {

	protected String name;

	public Fruit(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Fruit{" +
			"name='" + name + '\'' +
			'}';
	}

	public void setName(String name) {
		this.name = name;
	}
}
public class Apple extends Fruit{

	public Apple(String name) {
		super(name);
	}

	@Override
	public String toString() {
		return "apple";
	}
}
  • FruitRunner 클래스를 만든다.
  • callBananaFruit 메서드(1)는 Fruit 객체를 타입으로 갖는 제네릭 객체를 생성한다.
  • callApple 메서드(2)는 Fruit 객체를 상속받는 Apple 객체를 제네릭 객체를 생성한다.
  • printFruit 메서드(3)는 파라미터로 와일드카드를 사용하고, extends로 객체의 범위를 Fruit을 상속하는 객체로 제한했다.
public class FruitRunner {
    //1
	public void callBananaFruit() {
		TestWildcard<Fruit> wildcard = new TestWildcard<>();
		wildcard.setWildcard(new Fruit("banana"));
		printFruit(wildcard);
	}
   //2
	public void callApple() {
		TestWildcard<Apple> wildcard = new TestWildcard<>();
		wildcard.setWildcard(new Apple("apple"));
		printFruit(wildcard);
	}
    //3
	private void printFruit(TestWildcard<? extends Fruit> param) {
		Fruit value = param.getWildcard();
		System.out.println(value);
	}
}
  • extend를 사용해서 객체의 타입을 제한할 수 있다.

정리

  • 와일드 카드를 사용해서, 제너릭 객체에 여러 타입을 받을 수 있다.
  • 와일드 카드는 메서드의 파라미터로 사용하는 것이 좋다. 객체 생성 시 사용하게 되면 에러가 난다.
  • 와일드카드만 사용한다면 모든 타입이 가능하지만, extend를 사용하면 객체의 타입을 제한할 수 있다.

Reference

profile
집중

0개의 댓글