Coding/언어-JAVA

JAVA Generic 2/1 #Day6

꿀딴지- 2023. 8. 9. 14:33

제네릭(Generic) : 클래스 내부에서 사용할 데이터 타입을 외부에서 지정. 타입을 구체적으로 지정하는 것이 아니라 추후에 지정할 수 있도록 일반화

  • 객체별로 다른 타입의 자료가 저장될 수 있으며,
  • 인터페이스, 클래스, 필드, 메서드, 등.. 앞에 붙어서 사용가능
    • 제네릭 클래스(클래스명 <T>) : 클래스가 인스턴스화 될 때 타입 지정
    • 제네릭 메서드(<T> void 메서드명) : 메서드가 호출될 때 타입 지정
public Interface InterfaceName <T> {...} //제네릭(타입의) 인터페이스
public class ClassName <T> {//제네릭 클래스
	void setItem(T item) {...} //제네릭 파라미터 메소드
  	T getItem() {return item;} //제네릭 타입 반환 메소드 
} 
public class Student{ //일반 클래스
	public <T> T genericMethod(T o) {...}// 제네릭 메소드
} 

public class Main{
	public static void main(String[] args){
		ClassNmae<String> a = new ClassName<>(); //new 뒤쪽 타입 생략가능(jdk 1.7 이후)
		ClassName<Student> s = new ClassName<>(); //사용자정의한 객체도 타입변수로 올수 있음
	}
}
  • 제네릭 타입 매개변수
    • <> 다이아몬드 연산자 → 안에 식별자기호를 지정하여 파라미터화 함 ⇒ 타입 매개변수, 타입 변수
    • jdk 1.7 이후부터 new 생성자 뒤에 제네릭 타입 생략 가능
    • 암묵적으로 타입매개변수로 사용하는 char
      • <T> Type → S, U, V..…
      • <E> Element
      • <K> Key, K,V
      • <V> 리턴 값 또는 매핑된 값(Variable)
      • <R> Result
      • <N> Number

<장점>

  • 컴파일 타임에 타입 검사를 통해 예외 방지
  • → 타입이 지정되기 때문에 타입 안정성이 향상됨
  • 불필요한 캐스팅이 없어짐
  • → Object 타입 사용 시 Up/Down 캐스팅이 필요하고, 이 때 캐스팅이 잘못 되면 런타임시 오류 발생함
  • 코드 재사용성이 증가함 → 타입별로 클래스/메서드 만들 필요 없음

<주의사항>

  • 타입 파라미터로 명시할 수 있는 것은 참조타입(객체) 밖에 없음(원시 타입 → wrapper class로 객체로 변환필요)
  • 제네릭 타입의 객체는 생성 불가(선언은 가능함)
  • static 멤버에 제네릭 타입이 올 수 없음
  • static 메소드는 제네릭 가능(제네릭 클래스와 별도로 독립적인 제네릭이 사용 필요)

 

제네릭 클래스

public class Classname<K, V>{ //제네릭 클래스 : 클래스 내부에서 사용할 타입 매개변수 선언
	static V item2; //불가!!!. 클래스 변수는 타입매개변수 불가
	private K item; //가능. 제네릭 타입 변수

	void setItem(K item) { //제네릭 파라미터 메소드
        this.item = item;
    }

    K getItem() { //제네릭 타입 반환 메소드
        return item;
    } 
}
  • 클래스 변수에 타입매개변수 사용 불가
    • 클래스 변수 : 모든 인스턴스가 공유하는 변수 → 인스턴스 별로 달라지면? 안됨.

 

제네릭 메서드 : 클래스 내부의 특정 메서드만 제네릭으로 선언

[접근 제어자]  <제네릭타입>  [반환타입] [메소드명]([제네릭타입] [파라미터]) {...}

public class Classname<E>{ //제네릭 클래스 : 클래스 내부에서 사용할 타입 매개변수 선언
	private E item; //제네릭 타입 변수

	<E> E genericMethod(E o) {	// 제네릭 메소드 : 제네릭 클래스의 E타입과 독립적인 타입
			return o;
	}

	static E genericMethod(E o) {	// error! : static 메소드는 객체가 생성되기 이전에 메모리에 올라갔기 때문에 E를 클래스로부터 얻어올 수 없음.
        return o;
    }

	static <E> E genericMethod1(E o) { // 제네릭 메소드 : 제네릭 클래스의 E타입과 독립적인 타입
	  //**메서드 안에서 지역변수처럼 사용가능함 
		**return o;
	}
}
  • 제네릭 메서드의 타입 지정은 메서드가 호출될 때 지정(클래스명 앞에 선언한 타입 매개변수는 클래스가 인스턴스화 될 때 지정)
    → static 메서드 사용이 가능 : 제네릭 클래스와 별도로 독립적인 제네릭으로 사용해야함
  • 제네릭 클래스의 타입 매개 변수와 별개 : 클래스에서 지정한 제네릭 유형과 별도로 메소드에서 독립적으로 제네릭 유형 선언하여 사용
    → <>안의 타입을 파라미터로 보내 제네릭 타입을 지정함
  • 클래스에 선언된 T : 클래스 내에서 유효 // 메서드에 선언된 T : 메서드 내에서 유효 → 두개는 다름

'Coding > 언어-JAVA' 카테고리의 다른 글

JAVA 예외(try-catch) #Day7  (0) 2023.08.11
JAVA Generic 타입제한 2/2 #Day6  (0) 2023.08.10
JAVA Collection Framework 2/2 #Day5  (0) 2023.08.07
JAVA Collection Framework 1/2 #Day5  (0) 2023.08.07
JAVA 클래스, 메서드 구성 형태  (0) 2023.08.05