[JAVA] Generic

namdarine·2022년 1월 10일
1

JAVA

목록 보기
1/2

Generic

Using 'Generic', problems that may be used in the wrong type may be eliminated during the compiling. Generic is used widely in 'Collection', 'Lambda expression', 'Stream', and 'NIO'. Type can be used as a parameter when defining Class, Interface, and Method.
*Type parameter: When writing code, it is replaced with a specific type to generate various code.

Advantage

  1. JAVA compiler makes a strong type check on generic codes to eliminate problems caused by wrong used types.

  2. Eliminate unnecessary casting.

    list = new ArrayList();    //Non-generic
    list.add("Hello, world");
    String str = (String) list.get(0);
    
    List<String> list = new ArrayList<String>();    //Generic
    list.add("Hello, world");
    String str = list.get(0);
  1. Code becomes more reusable.

Generic type

It refers to class and interface with type as parameter. "< >" is attached after the class or interface name and the type parameter is located between them. Type parameters are not predetermined, so it is okay to designate them arbitrarily.

TypeExplain
TType
EElement
KKey
VValue
NNumber
    public class className <T> {
    	...
    }
    
    public interface interfaceName <T> {
    	...
    }

Type parameters can be made with the same rule as the variable name, but are generally expressed in one letter of alphabetic capital. 'Object' containing all object types may be used, but casting is required when saving and casting is aslo required when reading.

It is not necessary to use only one type parameter. Two or more type parameters may be used, which are referred to a 'multi-type parameters'. Each type parameter is divided into ','.

    //Before JAVA6
    Product<TV, String> product = new Product<TV, String>();
    //After JAVA7
    Product <TV, String> product = new Product<>();

Generic type also could be a parent class like other types.

    public class ChildClass<T, M> extends Class<T, M> {
    ...
    }
    
    // Child generic type may have additional type parameter.
    public class ChildClass<T, M, C> extends<T, M> {
    ...
    }

Generic Method (<T, R> R method (T t))

The generic method is a method with type parameters in parameter type and return type.

How to Declare

  1. add "< >" in front of the return type and describe the type parameter.
  2. Use the return type and type parameter.
    public <type parameter, ...> returnType methodName (parameter, ...) {
    ...
    }

How to Call

  1. Explicitly designating a specific type of type parameter in code.
  2. It is possible to allow the compier to estimate a specific type by looking at the type of the mediating value.
    returnType variance = <specific type> methodName (medium);
    returnType variance = methodName (medium);

Bounded type parameter

It is often necessary to specify a specific type specified in the type parameter. A generic method, for example, that calcuates numbers should have only instances of Number type or subclass type (Byte, Short, Integar, Long, Double) as a medium.

How to Declare

Put the keyword 'extends' after the type parameter, and specify the upper type.
*The upper type may be possible not only class also interface. Do not use 'implements' even interface.

    public <T extends upperType> returnType methodName (medium, ...) {
    ...
    }

The specific type specified in the type parameter possible an upper type or only a lower or an implementation class of an upper type. Note that what can be used as a type parameter variable within '{ }' of the method is limited to upper type members(fields, methods). Fields and methods that exist only in lower types cannot be used.

    public <T extends Number> int compare(T t1, T t2) {
    	double v1 = t1.doubleValue();    // doubleValue() of Number
        double v2 = t2.doubleValue();
        return Double.compare(v1, v2);
    }

Wildcard Type (<?>, <? extends ...>, <? super ...>)

When using the generic type as a medium or return type, a wildcard could be used instead of a specific type.

Category

  1. Generic type<?>: Unbounded Wildcard (No restrictions)
    It is used only when methods that do not depend on type parameters are used or when the functions provided by the Object method are sufficient.
    All classes or interface types could come as a specific type that replaces the type parameter. Internally it is defined and used as an Object, and all types can be recived as factors.

  2. Generic type<? extends upperType>: Upper Bounded Wildcards (Upper class restrictions)
    Only child classes of specific class are received as factors, and mainly used to alleviate the limitation of variables. As specific type that replaces the type parameter, only the lower type may come.

  3. Generic type<? super lowerType>: Lower Bounded Wildcards (Lower class restrictions)
    Only parent classes of specific class are received as factors, and as specific type that replaces the type parameter, only the upper type may come.


제네릭

제네릭을 사용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있다. 제네릭은 컬랙션, 람다식, 스트림, NIO에서 널리 사용된다. 클래스, 인터페이스, 메소드를 정의할 때 타입을 파라미터(parameter)로 사용할 수 있다.

*타입 파라미터: 코드 작성시 구체적인 타입으로 대체되어 다양한 코드를 생성하도록 해준다.

장점

  1. JAVA 컴파일러는 코드에서 잘못 사용된 타입때문에 발생하는 문제점을 제거하기 위해 제네릭 코드에 대해 강한 타입 체크(type check)를 한다.

  2. 불필요한 캐스팅을 제거한다.

    list = new ArrayList();   //비제네릭
    list.add("Hello, world");
    String str = (String) list.get(0);
    
    List<String> list = new ArrayList<String>();  //제네릭
    list.add("Hello, world");
    String str = list.get(0);
  3. 코드의 재사용성이 높아진다.

제네릭 타입

타입을 파라미터로 가진 클래스와 인터페이스를 말한다. 클래스나 인터페이스 이름 뒤에 "< >" 붙고 사이에 타입파라미터가 위치한다. 타입 파라미터는 정해져있는 것이 아니어서 임의로 지정해도 무방하다.

타입설명
TType
EElement
KKey
VValue
NNumber
    public class className <T> {
    ...
    }
    
    public interface interfaceName <T> {
    ...
    }

타입 파라미터는 변수명과 동일한 규칙으로 할 수 있지만, 일반적으로 알파벳 대문자 한 글자로 표현한다. 모든 객체 타입을 포함하는 'Object'를 사용해도 되지만, 저장할 때 캐스팅(casting)이 필요하고, 읽어올 때도 캐스팅(casting)이 필요하다.

타입 파라미터를 무조건 하나만 쓸 수 있는 것은 아니다. 두 개 이상의 타입 파라미터를 사용할 수 있고 이를 '멀티 타입 파라미터 (multi type parameter)'라고 한다. 각 타입 파라미터를 ' , '로 구분한다.

    //JAVA6 이전
    Product<TV, String> product = new Product<TV, String>();
    //JAVA7 이후
    Product <TV, String> product = new Product<>();

제네릭 타입도 다른 타입과 마찬가지로 parent class가 될 수 있다.

	public class ChildClass<T, M> extends Class<T, M> {
    	...
   	}
    
    	// 자식 제네릭 타입은 추가적으로 타입 파라미터를 가질 수 있음
    	public class ChildClass<T, M, C> extends Class<T, M> {
    	...
    	}

제네릭 메소드 (<T, R> R method (T t))

제네릭 메소드는 매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드이다.

선언방법

  1. 리턴 타입 앞에 '< >' 추가하고 타입 파라미터를 기술
  2. 리턴 타입과 매개 타입 파라미터를 사용
    public <type parameter, ...> returnType methodName (매개변수, ...) {
    ...
    }

호출방법

  1. 코드에서 타입 파라미터의 구체적인 타입을 명시적으로 지정
  2. 컴파일러가 매개값의 타입을 보고 구체적인 타입을 추정하도록 할 수 있음.
    returnType variance = <구체적인 type> methodName (매개값);
    returnType variance = methodName (매개값);

제한된 타입 매개변수 (Bounded type parameter)

종종 타입 파라미터에 지정되는 구체적인 타입을 지정할 필요가 있다. 예를 들어 숫자를 연산하는 제네릭 메소드는 매개값으로 Number 타입 또는 하위 클라스 타입 (Byte, Short, Integar, Long, Double)의 인스턴스만 가져야한다.

선언방법

타입 파라미터 뒤에 'extends' 키워드를 붙이고 상위 타입을 명시한다.
*상위 타입은 클래스뿐만 아니라 인터페이스도 가능하다. 인터페이스라고 'implements' 사용하지않는다.

    public <T extends 상위타입> returnType methodName (매개변수, ...) {
    ...
    }

타입 파라미터에 지정되는 구체적인 타입은 상위 타입이거나 상위 타입의 하위 또는 구현 클래스만 가능하다. 주의할 점은 메소드의 '{ }' 안에서 타입 파라미터 변수로 사용 가능한 것은 상위 타입의 멤버 (필드, 메소드)로 제한한다. 하위타입에만 있는 필드와 메소드는 사용할 수 없다.

    public <T extends Number> int compare(T t1, T t2) {
    	double v1 = t1.doubleValue();	//Number의 doubleValue()
    	double v2 = t2.doubleValue();
    	return Double.compare(v1, v2);
    }

와일드카드 타입 (<?>, <? extends ...>, <? super ...>)

제네릭 타입을 매개값이나 리턴 타입으로 사용할 때 구체적인 타입 대신에 와일드카드를 사용할 수 있다.

종류

  1. 제네릭 타입<?>: Unbounded Wildcard (제한없음)
    타입 파라미터에 의존하지 않는 메소드만을 사용하거나 Object method에서 제공하는 기능으로 충분한 경우에 사용된다.
    타입 파라미터를 대치하는 구체적인 타입으로 모든 클래스나 인터페이스 타입이 올 수 있다. 내부적으로는 Object로 정의 되어서 사용되고, 모든 타입을 인자로 받을 수 있다.

  2. 제네릭 타입<? extends 상위 타입>: Upper Bounded Wildcards (상위 클래스 제한)
    특정 클래스의 자식 클래스만 인자로 받으며, 주로 변수의 제한을 완화하게 하기 위해서 사용된다. 타입 파라미터를 대치하는 구체적인 타입으로 하위 타입만 올 수 있다.

  3. 제네릭 타입<? super 하위 타입>: Lower Bounded Wildcards (하위 클래스 제한)
    특정 클래스의 부모 클래스만 인자로 받으며, 타입 파라미터를 대치하는 구체적인 타입으로 상위 타입이 올 수 있다.

Reference

0개의 댓글