Java/JAVA 100 문제 풀이

자바 part.5 문제풀이 - 제네릭(Generic)의 필요성 및 편리성

진이최고다 2023. 7. 31. 22:37
예제
class Sample{
	//Field
	private Object obj;
	
	//Constructor
	Sample(Object x){
		this.obj = x;
	}

	//Method
	public Object getObj() {
		return obj;
	}
	
	void printlnfo() {
		System.out.println(obj.getClass().getName()); //객체가 속하는 클래스의 정보를 출력하는 메서드
	}
}

public class Collection_Generic01 {
	
    public static void main(String[] args) {
    	
    	//[1] : 객체생성 -> String
    	System.out.println("---객체 생성(String)---");
    	Sample s1 = new Sample("안녕하세요.");
    	System.out.println(s1.getObj());
    	s1.printlnfo();
    	System.out.println("");
    	
    	//[2] : 객체생성 -> 숫자
    	System.out.println("---객체 생성(int)---");
    	Sample s2 = new Sample(100);
    	System.out.println(s2.getObj());
    	s2.printlnfo();
    	System.out.println("");
    	
    	//[3] : 객체 생성 -> Objet
    	System.out.println("---객체 생성(Object)---");
    	Sample s3 = new Sample(new Object());
    	System.out.println(s3.getObj());
    	s3.printlnfo();
    	System.out.println("");
    	
    	//[4] : 위와 같이 사용시 -> 단점
    	//s1 -> 문자열
    	//Object str = s1.getObject -  리턴시 반환 타입이 Object이다.
    	//System.out.println(str.length()); 오류
    	String str = (String)s1.getObj(); //형변환
    	System.out.println(str.length()); //6
    	
    	//s2 -> 숫자
    	//Object num = s2.getObj();
    	//System.out.println(num + 100); 오류
    	int num = (int)s2.getObj();    //형변환
    	System.out.println(num + 100); //200  	
    }
}

1. 제네릭의 필요성

제네릭은 자바에서 다양한 타입을 안정적으로 처리할 수 있게 하는 기능이다. 제네릭을 사용하지 않는 코드는 다양한 타입을 처리하기 위해 "Object"를 사용하는 경우가 많다. 그러나 이러한 방식은 런타임에 타입 캐스팅 문제를 일으킬 수 있으며, 컴파일러는 이러한 문제를 알아내지 못한다.

 

위 예제에서, "Sample" 클래스는 어떤 타입의 객체든 저장하고 출력할 수 있다. 이를 통해 재사용성이 높아지지만, "getObj" 메서드의 반환 타입이 "Object" 이므로, 반환 받은 객체를 사용하려면 원래 타입으로 형변환하여야 한다. 이는 코드가 복잡해지고, 런타임에서 잘못된 캐스팅으로 인한 오류가 발생할 수 있다.

 

2. 제네릭의 편리성

제네릭을 사용하면 이러한 문제를 해결할 수 있다. 제네릭을 이용하면, 클래스나 메서드가 처리할 타입으로 동적으로 지정할 수 있다. 따라서 반환 받은 객체를 원래 타입으로 캐스팅하는 과정 없이도 타입의 객체를 사용할 수 있다.

 

위의 예제에서 제네릭을 적용하면, "Sample" 클래스를 "Sample<String>", "Sample<Integer>"등으로 사용할 수 있으며, "getObj" 메서드는 각각 "String, Integer"타입의 객체를 반환하게 된다. 이를 통해, 잘못된 타입 캐스팅으로 인한 런타입 오류를 예방하고, 코드를 더욱 간결하게 작성할 수 있다.