Java에서 제네릭?

Generic programming is a style of computer programming in which algorithms are written in terms of types to-be-specified-later that are then instantiated when needed for specific types provided as parameters. This approach, pioneered by ML in 1973,[1][2] permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication. Such software entities are known as generics in Ada, C#, Delphi, Eiffel, F#, Java, Rust, Swift, TypeScript and Visual Basic .NET. They are known as parametric polymorphism in ML, Scala, Haskell (the Haskell community also uses the term "generic" for a related but somewhat different concept) and Julia; templates in C++ and D; and parameterized types in the influential 1994 book Design Patterns.[3] The authors of Design Patterns note that this technique, especially when combined with delegation, is very powerful, however, Dynamic, highly parameterized software is harder to understand than more static software.

사전적 정의: characteristic of or relating to a class or group of things; not specific
클래스나 어떤 집합의 특징? 확실하지 않은 것?

한줄 설명

  • Generic은 문법인데 어떤 문법이냐면 다양한 메소드를 사용할 때 클래스를 사용해 객체를 Instantiate 할 때 필요한 Type을 지정해줄 수 있도록 프로그래밍하는 문법이다.

한 가지 Type만을 사용하는 것이 아니라 사용하는 사용자가 원하는 타입을 코디하는 그때 그때 선택적으로 지정해 사용할 수 있다.

제네릭 프로그래밍은 컴퓨터 프로그래밍 방법 중 하나인데 메소드를 사용하거나 클래스를 정의할 때 사용할 타입을 정하지 않고 임의의 타입(Generic)을 사용하고 실제로 원하는 자료값의 타입은 사용할 때 선언할 수 있는 방식이라고 이해가 된다.
(수정 중 입니다)

어떻게 사용 하나?

클래스

class GenericStack<T> {
    stack: T[];

    constructor() { 
        this.stack = [];
    }

    addItem(item: T): void {
        this.stack.push(item);
    }

    toString(): string { 
        return this.stack.join(', ');
    }

    get(index?: number): any { 
        return index ? this.stack[index] : this.stack;
    }


}
const stringStack = new GenericStack<string>();
const numberStack = new GenericStack<number>();

stringStack.addItem('hi');
stringStack.addItem('hello');
console.log(stringStack.toString());

numberStack.addItem(1);
numberStack.addItem(5);
numberStack.addItem(6);
console.log(numberStack.toString());

const wild = new GenericStack<any>();

wild.addItem(1);
wild.addItem('victor');
wild.addItem(function () { return '1111' });
console.log(wild.toString());
const f = wild.get(2);
const arr = wild.get();
console.log('stack? ', arr);

요렇게 클래스를 정의할 때 임의의 자료타입 T 를 사용하고 실제 클래스를 사용해 객체를 instantiate할 때 사용할 Type을 지정해준다.

함수

function identify<T>(arg: T): any {
    return arg;
}
const numberArg = identify<number>(5);
const stringArg = identify<string>('STRING');

요렇게 함수를 사용할 때 필요한 Type을 지정해서 사용할 수 있다.
함수 하나가 여러 Type늘 수용할 수 있도록 정의 가능하다.

Generic을 사용해 코딩할 때 장점

Stronger type checks at compile time.
Fixing compile-time errors is easier than fixing runtime errors
Elimination of casts. Which in turn is quicker.
Enabling coders to implement generic solutions, which can be reused for multiple purposes.
Future proofed for the datatypes of tomorrow.

  • 컴파일 시 타입체킹을 확실히 할 수 있다
  • 런타임 에러보다 컴파일 에러를 수정하는게 편하다
  • 타입변환(casting)을 안 해도 되니 빨라진다.
  • 하나 잘 만들어서 여러 목적으로 사용할 수 있다.
  • 조작해야 하는 데이터의 타입이 보장된다.

참고