2011년 6월 13일 월요일

Java Generic Quick Tutorial

원문: http://www.javacodegeeks.com/2011/04/java-generics-quick-tutorial.html

Java Generic Quick Tutorial

Generic은 Java 5.0에서 소개되었습니다. 하지만 아직도 많은 Java 개발자들은 Generic의 의미를 아직 이해하지 못하고 있는 것 같습니다.

본 문서에서 그 이해를 돕고자 Generic의 의미 및 사용 방식을 설명하고자 합니다.

The Simplest Way!
Generic 사용의 가장 간단한 방법은 Object Casting을 쉽게 할 수 있다는 것입니다.

List<Apple> box = ...;
Apple apple = box.get(0);

List을 선언할 때 담을 수 있는 Object Type을 지정합니다. 이러면 List에서 꺼내올 때 지정된 Type으로 가져올 수 있는 겁니다.
아직도 아래처럼 하시는 분들이 계신가요?

List box = ...;
Apple apple = (Apple) box.get(0);

Generic은 4곳에서 정의하여 사용할 수 있습니다.
1. Generic class Declarations
2. Generic interface Declarations
3. Generic method Declarations
4. Generic constructor Declarations

Generic Classes and Interfaces
public interface List<T> extends Collection<T> {
...
}

java.util.List Interface을 보면 위처럼 정의 되어 있다. 사용자가 지정하는 Object Type을 T라고 임의로 명시한 것이다.
또한, List의 “get” Method는 “T”를 Return 하게 정의되어 있다.

T get(int index);

Generic Methods and Constructors
Method 레벨에서 Generic 사용을 정의해야 한다면 아래와 비슷한 유형일 것입니다.

public static <t> T getFirst(List<T> list)

간단한 사용예들...

Type Safety When Writing...
List<String> str = new ArrayList<String>();
str.add("Hello");
str.add("World");

List<String>으로 선언되었다면 이 List에는 String Type만 넣을수 있습니다.. String 아닌 다른 타입을 넣는다면 compile time에 에러가 발생하게 됩니다.. Generic을 사용하지 않았다면 Type Error는 Runtime에 발생했을 것입니다. 결국 이것을 Compile time에서 확인할 수 있다는 것은 그만큼 프로그램의 안정성이 확보된다 생각할 수 있습니다.

str.add(1); → compile error 발생

… and When Reading

또한, List<String>에서 꺼내는 객체는 모두 String Type입니다.

Iterating

Iterator에 Generic을 사용한다면 hasNext(), next() Method에서 Object Casting이 없어 Code을 간략하게 할 수 있습니다.

for (Iterator<String> iter = str.iterator(); iter.hasNext();) {
String s = iter.next();
System.out.print(s);
}

Using foreach
위의 Code는 For each 문법을 사용하면 더욱 간략해질 수 있습니다.

for (String s: str) {
System.out.print(s);
}

Autoboxing and Autounboxing
boxing이라는 것은 Java 기본형 변수 8가지를 Wrapper Class로 변환해주는 작업을 말합니다. Autoboxing은 변환이 자동화 된다는, 그리고 Autounboxing은 Wrapper Class에서 기본형 변수로 변환도 자동화 된다는 것입니다. 이 기능이 있기 전에 boxing을 하나하나 Code로 작성했어야 했었습니다.

List<Integer> ints = new ArrayList<Integer>();
ints.add(0);
ints.add(1);

int sum = 0;
for (int i : ints) {
sum += i;
}


PS: 원문에는 Subtype간의 Generic문제에 관해서도 언급되어 있습니다. 꼭 한 번씩 읽어 보시길 추천합니다.

댓글 없음:

댓글 쓰기

시스템 부팅시 도커 컨테이너 자동 실행

Docker 컨테이너를 운용중인 시스템이 Reboot 되버리면 컨테이너가 자동으로 올라오지 않아 불편해서 시스템 리붓시 컨테이너를 자동으로 시작되게 init 데몬에 등록하기로 했습니다. 서버는 Ubuntu 17.10 Docker는 17.0...