Java_study_14 (제네릭)

Java_study_14 (제네릭)

♨학습내용

더보기 ☞ 제네릭 사용법 ☞ 제네릭 주요 개념 (바운디드 타입, 와일드 카드) ☞ 제네릭 메소드 만들기 ☞ Erasure

제네릭 사용법

제네릭 이란?

- 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법이다.

- 제네릭은 중복 코드의 제거를 위해 자바 5 부터 나왔다.

- 객체의 타입을 컴파일 시에 체크해 객체의 타입 안정성 을 높이고 형변환의 번거로움이 줄어든다.

- 제네릭 장점

1. 타입 안정성을 제공한다.

2. 타입체크와 형변환을 생략할 수 있으므로 코드가 간결해진다.

제네릭 사용법

- 제네릭 타입(class, interface)

- 타입을 파라미터로 가지는 클래스와 인터페이스이다.

- 클래스 or 인터페이스 뒤에 '<>' 부호가 붙고, 사이에 타입 파라미터가 위치한다.

- 일반적으로 타입 파라미터는 대문자 알파벳 한 글자로 표현한다.

- 타입의 매개변수의 이름은 아무거나 들어가도 상관없지만, 공식문서의 Name Convention을 따르는 게 좋습니다.

public class 클래스명 { } public interface 인터페이스명 { }

E : 주로 자바 Collection framework에 사용되는 Element

K : map에서 매개변수로 사용되는 Key

V : map에서 매개변수로 사용되는 Value

N : 숫자를 나타내는 Number

T : 일반적으로 사용하는 제네릭 Type

S : 두번째로 사용하는 일반 제네릭 Type

U : 세번째로 사용하는 일반 제네릭 Type

V : 네번째로 사용하는 일반 제네릭 Type

멀티 타입 파라미터(class, interface)

- 제네릭 타입은 두 개 이상의 멀티 타입 파라미터를 가질 수 있다.

public class Product { private T kind; private M model; public T getKind() { return this.kind; } public M getModel() { return this.model; } public void setKind(T kind){ this.kind = kind; } public void setModel(M model){ this.model = model;} }

제네릭 주요 개념 (바운디드 타입, 와일드 카드)

바운디드 타입

- 바운디드 타입 매개변수는 특정 타입의 서브타입으로 제한 하는 것을 말한다.

- 클래스, 인터페이스, 메소드를 제네릭으로 작성할 때, 타입 변수를 제한하기 위해서는 Bounded Type으로 선언해야한다.

- 으로 타입변수를 지정하여 상위타입의 하위클래스로만 제한할 수 있다.

public class Example { public static void main(String[] args) { // bounded 내의 타입이 아니여서 컴파일 오류 발생 // BoundedGeneric boundedGeneric = new BoundedGeneric(); BoundedGeneric boundedGeneric = new BoundedGeneric<>(); boundedGeneric.setT(Integer.valueOf(10)); boundedGeneric.print(); } } class BoundedGeneric{ T t; public void print(){ System.out.println(t); } public void setT(T t){ this.t = t; } }

와일드 카드

- 제네릭에서 와일드 카드는 로 나타내며 알 수 없는 유형을 나타낸다.

- 와일드 카드는 파라미터 변수, 필드, 지역변수의 타입 그리고 리턴 타입에도 사용될 수 있다.

- 그러나 와일드 카드는 제네릭 메소드 호출, 제네릭 클래스 인스턴스 생성 또는 수퍼 타입의 타입 인자로는 사용될 수 없다.

import java.util.Arrays; import java.util.List; public class Example { public static double sum(List numberlist){ double sum = 0.0; for(Number n : numberlist){ sum+=n.doubleValue(); } return sum; } public static void main(String[] args) { List integerList = Arrays.asList(3, 6, 9); System.out.println("sum : "+sum(integerList)); // 18.0 List doubleList = Arrays.asList(3.3, 6.6, 9.9); System.out.println("sum : "+sum(doubleList)); // 19.8 } }

제네릭타입 : Unbounded Wildcards(제한없음) 타입 파라미터를 대치하는 구체적인 타입으로 모든 클래스나 인터페이스 타입이 올 수 있다.

: Unbounded Wildcards(제한없음) 제네릭타입 : Upper Bounded Wildcards(상위클래스 제한) 타입 파라미터를 대치하는 구체적인 타입으로 상위 타입이나 하위 타입만 올 수 있다.

: Upper Bounded Wildcards(상위클래스 제한) 제네릭타입 : Lower Bounded Wildcards (하위클래스 제한) 타입 파라미터를 대치하는 구체적인 타입으로 하위 타입이나 상위 타입이 올 수 있다.

: Lower Bounded Wildcards (하위클래스 제한)

제네릭 메소드 만들기

- 클래스가 전부가 아닌 메서드 하나에 대해 제네릭으로 정의할 수 있다.

class BoxFactory { public Box makeBox(T o) { Box box = new Box(); box.set(o); return box; } }

- 제네릭 클래스는 인스턴스 생성 시 타입 인자를 결정하지만

- 제네릭 메서드는 메서드 호출 시점에 결정한다.

Box sBox = BoxFactory.makeBox("Hello"); Box dBox = BoxFactory.makeBox(3.69);

- 다음과 같이 타입 인자 생략이 가능하다.

Box sBox = BoxFactory.makeBox("Hello"); Box dBox = BoxFactory.makeBox(3.69);

- double의 경우 wrapper클래스 Double형으로 오토박싱이 진행된다.

- 제네릭 메서드는 메서드 호출 시 전달되는 인자의 자료형을 근거로 판단한다.

Erasure

- 자바는 하위 호환성을 지키기 위해 타입 소거를 만들었다.

- 제네릭의 타입 소거는 원소 타입을 컴파일 시기에만 검사하고 런타임에는 해당 타입의 정보를 알 수 없다는 개념이다.

- 이러한 개념이 나온 이유는, 제네릭 개념을 도입한 이후로 이전 버전의 자바와의 하위 호환성때문이다.

- Non-Reifiable Type 런타임에 타입 정보의 유무에 따라 타입을 나누는 개념이다.

Refiable type : 런타임에 타입에 대한 정보를 가지고 있다.

primitive, non - generic, unbounded wildcards () 등 이 있다.

primitive, non - generic, unbounded wildcards () 등 이 있다. Non - Reifiable type : 런타임에 타입에 대한 정보가 없다.

type erasure 가 진행되는 대부분의 generic parameterized type 이 있다.

from http://hjshims.tistory.com/105 by ccl(A) rewrite - 2021-09-20 15:27:26