2009. 3. 17. 13:14

JDK 5.0 에서의 새로운 변화





 

JDK 5.0 에서의 새로운 변화

JDK 5.0에서는 프로그래밍의 유연함을 좀더 향상시키기 위해서 여러 가지 기능들이 개선되고 추가되었다. 이번 절에서는 JDK 5.0 에 오면서 변화된 여러 기능을 알아보자. 그렇지만 자바를 처음접하는 이들에게는 전혀 이해가 안 되는 얘기들일 것이다. 따라서 모든 내용을 이해할 생각을 하지 말고 그냥 "이런 것이 있구나!"하고 참고적으로 알아두길 바란다. 그렇다고 그냥 넘어가지 말자. 이전 버전과 비교해서 달라진 부분을 알고 있다면 향후 프로그래밍을 할 때 크게 도움을 받을 수 있기 때문이다.

less..

1. 제네릭타입(Generic Type)

예전부터 자바 커뮤니티의 기대를 받아왔던 제네릭 타입(Generic Type)이 드디어 JDK 5.0 버전의 일부로 포함되었다. 제네릭 타입이 적용된 것을 Collection API에서 가장 먼저 찾아볼 수 있다. Collection API 는 Linked List, ArrayList, 그리고 HashMap과 같이 하나 이상의 클래스가 공통으로 사용할 수 있는 기능들을 제공한다.

JDK 5.0 버전 이전의 Collection API 에서는 COllection 객체를 Onject 클래스에 저장하기 때문에 컴파일 타임에 발생하는 타입 오류(Type Mismatch)을 확인할 수 없다. 이러한 문제는 런타임할 때 ClassCastException이 발생하는 형태로 확인해야 하므로 Collection에 대입된 자료의 확인 여부를 어쩔 수 없이 런타임할 때까지 유도해야만 확인할 수 있었다.

하지만 JDK 5.0에서는 이러한 번거로움을 탈피하기 위해서 일반화된 API를 사용하려면 컴파일 할 때 단지 <> 사이에 사용할 자료 타입을 선언해주기만 하면 캐스팅은 더 이상 할 필요가 없다. 나아가서 사용된 Collection에 삽입되는 객체의 자료타입이 잘못 대입될 경우, 이젠 런타임 때가 아닌 컴파일 때에 확인할 수 있다. 예를 들어, 옷을 직접 입지 않고 옷의 사이즈를 확인하는 것만으로 내게 맞는 옷인지 확인할 수 있게 된 것이다.


2. 메타데이터

JDK 5.0에 포함된 ‘메타데이터(Metadata)' 기능을 통해 자바 클래스, 인터페이스, 메서드, 그리고 필드(변수나 상수) 등에 추가적인 정보들을 부과할 수 있게 되었다. 이 추가적인 정보는 javac 컴파일러 외에도 여러 툴로부터 읽어 들일 수 있으며 설정하기에 따라 클래스 파일에 저장할 수도 있고 Java Reflection API를 통해 런타임할 때에 접근할 수도 있다.

아무래도 메타데이터가 JDK 5.0에 추가된 주된 이유는 여러 개발 툴과 런타임 툴간의 공통된 인프라를 구축함으로써 프로그래밍과 개발에 소요되는 수고를 덜고자 하기 위함이라 볼 수 있다.


3. 개선된 루프

Collection API의 iterator는 상당히 자주 사용되는 객체다. 이는 Collection 내에서 이동하는 기능을 제공하는데, 개발을 하다보면 이런 Collection 들과 배열들을 반복적으로 사용할 때가 많다. 하지만 iterator와 인덱스 변수들로 인해 복잡함과 다소 불편함을 느낄 때가 많다. ‘개선된 루프(Enhanced for Loop)'는 그런 불편함에서 나올 수 있는 오류 발생 가능성을 줄여준다. 컴파일러는 필요한 루프 코드를 생성하게 되고, Generic Type을 함께 사용하게 되면 더 이상 일일이 자동 형 변환(casting)을 해주지 않아도 되므로 프로그래밍을 하는 데 더욱 더 편해진다.

예를 들어, 기차를 탈 때와 비슷하다. 기차를 이루는 각각의 호차들마다 번호표가 있게 마련인데, 호차마다 이 번호표가 없다고 가정해보자. 그렇다면 모든 승객들이 맨 앞의 기차부터 일일이 숫자로 세어 자신이 배정받은 호차에 타게 되는 불편함이 있게 된다. 그리고 숫자로 호차들을 세다가 중간에서 잘못 세게 되면 다른 사람 자리로 모든 호차들을 미리 나열화하고 그 호차들에게 번호표를 미리 붙여놓음으로써 불편함을 줄여놓은 것이다. JDK 5.0에서 얘기하는 ‘개선된 루프’가 바로 이와 비슷한 반복적 비교문을 강화한 것이다.

[이전버전]
 for(int i=0 ; i<10 ; i++)
  System.out.println(ar[i]);

[JDK 5.0]
 for(string n : ar)
  System.out.println(n);

위 예문과 같이 [이전버전]에서는 int형 변수 i와 같은 index값을 사용하여 배열의 요소들을 참조하는 데 사용한다. 하지만 배열의 길이가 만약 9개라면 6장에서 배우게 되는 예외 중 하나인 ArrayIndexOutBoundsException이 발생하게 된다. 하지만 [JDK 5.0]에서 제공되는 개선된 루프를 사용하게 되면 내부적으로 나열화 작업이 자동적으로 이루어지므로 [이전버전]의 예문과 같이 예외에 대한 우려는 하지 않아도 된다.


4. 오토박싱 / 언박싱

int 또는 bollean 과 같은 기본 자료형(primitive Type)과 이에 상응하는, 즉 Integer 또는 Boolean과 같은 Wrapper 클래스 타입간의 자료 변환 작업이 EO로는 불필요할 정도의 많은 코딩을 요구하는 경우 있다. 특히 Collection API 중 메서드의 인자로서 사용하기 위한 경우라면 더더욱 골치 아픈 일이 될 수 있었는데, JDK 5.0 에서는 int와 Integer같의 변환 작업을 컴파일러가 맡아서 처리하므로 불필요함을 크게 줄이게 되었다.

간단하게 예를 들자면 어느 날 집으로 새로운 컴퓨터가 배달되었다. 기분이야 두말하면 잔소리지만 포장을 뜯는 것이 여간 신격 쓰이는 것이 아니다. 물론, “기분이 날아갈 듯한데 그게 무슨 대수냐?”라는 생각이 들지도 모른다. 하지만 고객이 원한다면 이런 “포장까지 깔끔하게 서비스 해주는 택배회사가 있다면...”이라는 생각을 한 번쯤은 해봤다(아마 대박이 날지도 모를 일이다.) JDK 5.0 에서는 이런 귀찮은 변환 작업을 자동적으로 제공하는데, 이를 ‘오토박싱/언박싱(Autoboxing/Unboxing)'이라 하는 것이다.

이전 버전에서는 Ingeter 클래스의 내부값을 int로 가져오려면 그러한 일을 해주는 특정 메서드를 호출해야만 하는데, JDK 5.0으러 오면서 그런 수고를 덜었다.

[이전버전]
 Integer iTest = new Integer(500);
 int i = iTest.intValue();

[JDK 5.0]
 Integer iTest = new Integer(500);
 int i = iTest;

간단히 정리하면, 위 예문의 핵심은 마치 객체가 기본 자료형에 대입되는 것처럼 보이지만 이때 변환작업을 컴파일러가 알아서 해준다는 것이다.


5. static import

static import 기능은 ‘import static'의 형태로 사용되는데, 이를 통해 클래스로부터 상속받지 않고 또는 해당 클래스를 일일이 명시하지 않고도 static 상수들에 접근할 수 있다. 다시 말해 기존과 같이 BorderLayout.CENTER라고 사용할 필요 없이 JDK 5.0에서 ’import static'을 적용한 이제부터는 단순히 CENTER라고만 해도 사용할 수 있다는 것이다.

[이전버전]
 JPanel p1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));

[JDK 5.0]
 import static java.awt.FlowLayout.*;
 ...
 JPanel p1 = new JPanel(new FlowLayout(RIGHT));

위의 [이전버전]과 [JDK 5.0]의 예문이 너무 간단하여 [JDK 5.0]에서 크게 유익한 점을 못 느낄 수도 있다. 하지만 실제 예제를 다루게 되면 그렇지가 않다. 하지만 실제 예제를 다루게 되면 그렇지가 않다. 또는 System.out.println("..."); 이라는 문장이 많이 사용될 경우 out까지를 static import로 미리 적용해두면 코드의 내용이 상당히 편리해질 것이다.


6. Formatter과 Scanner

이제 JDK 5.0 버전에서는 Formatter 클래스가 제공되는데, 이를 C style format imput / output 이라 하여 C 언어에서 사용되었던 printf 형태의 기능이 추가되어 정형화된 출력을 할 수 있게 되었다. 더 나아가 이로써 같은 텍스트 형태를 유지하면서 큰 수정 작업 없이 C 언어의 응용프로그램으로부터 소스를 물려받아 자바로의 변환(migration)도 쉽게 할 수 있다. 다음은 예문이다.

 System.out.printf("%s %5d%n", "총점:“, 500);

이 예문처럼 %로 시작하는 포맷 형식을 설정하고 그 형식에 맞도록 정형화된 출력을 목적으로 하는 것이 Formatter다.

Scanner 클래스는 기존에 사용되었던 Stream들에 없었던 파싱(parsing) 기능을 부여하여 효율적으로 자료를 유입하기 위한 클래스다. 기존의 Stream들은 Character 기반의 Stream인 BufferedReader를 쓴다하더라도 한 번에 한 줄씩 읽어 들이는 수 밖에 없었다. 하지만 Scanner 클래스를 사용하면 한 번에 전체를 읽어 들일 수도 있으며, 때에 따라서는 한 줄 단위로 읽을 수도 있다. 이러한 것들은 Pattern 클래스 또는 문자열로 되어 dLT는 구분자의 패턴을 useDelimiter()라는 메서드로 간단하게 변경하여 유연성을 높이고 있다.


7. Varargs(Variable Arguments)

JDK 5.0 이전의 버전에서는 특정 메서드를 정의할 때 인자(argument)의 타빙과 수를 정해두고 호출할 때 전달되는 인자의 수가 일치하지 않을 경우에는 메서드를 호출할 수 없었다. 이런 문제로 인해 많은 개발자들이 오버로딩법 또는 메서드에 배열객체로 인자를 지정하고 배열 객체를 사용하여 이 문제를 해결했지만 매번 호출할 때의 배열화 작업이 너무 불편했던 것이 사실이다.

이제 varargs 기능을 사용하여 여러 개의 인자를 매개변수(parameter)의 형태로 전달할 수 있다. 인자로 받는 메서드에서 ‘...’이라고 명시를 해주면 이를 통해 메서드를 수행하는데 필요한 인자의 수를 유연하게 구현할 수 있다.

[이전버전]
 class VaraTest {
  public static void test(Object args){
   System.out.println(args);
  }
  public static void main(String args[]){
   test("Java5");
   test("Java5", " Varargs", " Test!"); // 인자 전달에 대한 오류!
  }
 }

[JDK 5.0]
 class HelloWorld {
  public static void test(Object ... args){
   for(int i = 0 ; i < args.length ; i++) {
    System.out.print(args[i]+",");
   }
   System.out.println();
  }
  public static void main(String args[]){
   test("Java5");
   test("Java5", " Varargs", " Test!");
   test(new Integer(1000), new Float(3.14));
  }
 }

[출력결과]
 Java5,
 Java5, Varargs, Test!,
 1000,3.14,

이전 버전에서는 인자의 수만 달라도 컴파일 오류가 발생했다. 하지만 JDK 5.0 에서는위처럼 Varargs 법을 사용하게 되면 보는 것과 같이 인자가 한 개이든, 세 개이든 인자의 수를 유연하게 받아주는 특징이 있어 작업의 효율을 높일 수 있다.


8. Simpler RMI interface generation 기법

원격 인터페이스에 대한 stub를 생성하는 데 있어서 더 이상 rmi 컴파일러인 rmic를 사용할 필요가 없으므로 RMI 기법을 더욱 더 간편하게 사용할 수 있게 되었다. Dynamic Proxy가 소개됨에 따라 stub가 제공하는 정보는 이제 런타임할 때 찾을 수 있게 되었기 때문이다.

이외에도 JVM 관련 기능들과 프로토콜을 감시하는 모니터링 기능 그리고 JDBC RowSets 등 여러 기능이 추가되고 개선되었다. 하지만 이 책의 수준에 맞춰 이 정도의 소개로 마무리하며 JDBC Rowstes 과 같이 꼭 알아야 하는 것들은 해당되는 장에서 소개한다.