윤제니

컬렉션 프레임워크 - 제네릭 본문

Java

컬렉션 프레임워크 - 제네릭

꿈다루 2020. 9. 11. 17:47

우리가 사용하는 프로그램은 대부분 데이터를 사용하여 구현한다.

프로그램을 실행할 때 데이터를 효율적으로 관리하기 위해 자료구조를 사용 

 

제네릭 

어떤 값이 하나의 참조 자료형이 아닌 여러 참조 자료형을 사용할 수 있도록 프로그래밍 하는 것 

어떤 변수가 여러 참조 자료형을 사용할 수 있도록 Object클래스를 사용하면 다시 원래 자료형으로 반환해 주기 위해 매번 형 변환을 해야함

 => 이러한 경우에 사용하는 프로그래밍 방식 

 

장점

  • 여러 참조 자료형이 쓰일 수 있는 곳에 특정한 자료형을 지정하지 않고, 사용하는 시점에 어떤 자료형을 사용할 것인지 지정 
  • 제네릭으로 구현하면 형 변환을 하지 않아도되기때문에 안정적이면서 형변환 코드가 줄어든다.
    1. 컴파일러는 일단 대입된 자료형이 잘 쓰였는지 확인. 
    2. class파일을 생성할 때 T를 사용한 곳에 지정된 자료형에 따라 컴파일 하므로 형 변환을 하지 않아도 된다. 
public class GenericPrinter<T> {
	private T material;
    
    public void setMaterial(T material){
    	this.material=material;
    }
    
    public T getMaterial(){
    	return material;
    }
}

여러 자료형으로 바꾸어 사용할 material 변수의 자료형을 T라고 작성. 이때 T자료형 매개변수(type parameter)라고 부른다.

클래스이름GenericPrinter<T>라고 정의하고 나중에 클래스를 사용할 때 T 위치에 실제 사용할 자료형을 지정한다. 

클래스의 각 메서드에서 해당 자료형이 필요한 부분에는 모두 T문자를 사용하여 구현한다. 

 

*위의 코드를 보며 제네릭 클래스를 사용해보자*

 => 파우더가 재료인 프린터는 다음과 같이 선언하여 생성한다.

GenericPrinter<Powder> powderPrinter=new GenericPrinter<Powder>();
powderPrinter.setMaterial(new Powder());
Powder powder=powderPrinter.getMaterial(); //명시적 형 변환 하지 않음.

T로 정의한 클래스 부분에 Powder형을 넣어 주고, T형 매개변수가 필요한 메서드에 Powder 클래스를 생성하여 대입해 준다. 

GenericPrinter<Powder>에서 어떤 자료형을 사용할지 명시 했으므로 getMaterial() 메서드에서 반환할 때 형 변환을 하지 않는다.

 => 실제 제네릭 클래스를 사용할 때 T 위치에 사용한 Powder형'대입된 자료형' 이라 한다. 

      Powder를 대입해 만든 GenericPrinter<Powder>'제네릭 자료형' 이라 한다. 

 

 

자바 7 부터는 제네릭 자료형의 클래스를 생성할 때 생성자에 사용하는 자료형을 명시하지 않아도 되며, <> 다이아몬드 연산자라고 한다.

=> 선언된 자료형을 보고 생략된 부분인 String임을 컴파일러가 유추할 수 있기 때문에 생성 부분에서 생략 가능. 

ArrayList<String> list=new ArrayList<>();

 

 

 

자료형 매개변수 T와 static

static 변수나 메서드는 인스턴스를 생성하지 않아도 클래스 이름으로 호출이 가능하며, static 변수는 인스턴스 변수가 생성되기 이전에 생성된다. 또한 static 메서드에서는 인스턴스 변수를 사용할 수 없다. 

T의 자료형이 정해지는 순간제네릭 클래스의 인스턴스가 생성되는 순간이다. T의 자료형이 결정되는 시점보다 빠르기 때문에 

static 변수의 자료형이나 static 메서드 내부 변수의 자료형으로 T를 사용할 수 없다.