본문 바로가기

Java & Html

Java7 특징 10가지

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

Java7 특징 10가지

Java8이 나온지 3달이 다 되가는 시점에 Java7 정리라니!? 개인적으로 Java6 환경에서만 개발하다보니 Java7 변경점도 가물가물한 상황이고 때마침 JavaRevisited에 Java7 Features에 대한 기사가 올라와서 겸사겸사 정리해봅니다.

1. Type Inference

Java7 이전에는 제너릭 타입 파라미터를 선언과 생성시 중복해서 써줘야했는데요. 다이아몬드 연산자(<>) 지원으로 제너릭 사용이 간편해졌습니다.
아래 코드를 보면 생성자 영역의 타입 파라미터들은 <>로 대체 가능합니다. 컴파일러가 해당 타입을 유추해서 컴파일시 자동으로 캐스팅 코드를 추가 해줍니다.

JDK 7 이전

1
2
Map<String, List<String>> employeeRecords = new HashMap<String, List<String>>();
List<Integer> primes = new ArrayList<Integer>();

JDK 7

1
2
Map<String, List<String>> employeeRecords = new HashMap<>();
List<Integer> primes = new ArrayList<>();

물론 기존에도 제너릭 메소드를 제공함으로써 Type Inference가 가능했는데요. 예를 들어 Static Factory Method를 아래처럼 사용하면 별도의 타입 파라미터 없이도 간단히 제너릭 객체를 리턴 받아 사용 가능합니다. Guava 라이브러리 등에서 자주 사용하던 방식입니다.

1
2
3
4
5
public static <K,V> HashMap<K,V> newContacts() {
   return new HashMap<K,V>();
}
 
HashMap<String, Set<Integer>> contacts = newContacts();

하지만 Java7에서는 스펙 자체에 <> 연산자가 추가되어 굳이 불필요한 Static Factory Method를 안만들어도 된다는 장점이 있겠죠?
<> 조차 사용 안하면 어때?라는 생각도 들지만 제너릭 지원 이전의 버젼 호환성을 위해서는 새로운 연산자의 등장은 어쩔 수 없는 선택이었나 봅니다.

2. String in Switch

Switch문 내에서 문자열 사용이 가능해졌습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
switch (day) {
    case "NEW":
        System.out.println("Order is in NEW state");
        break;
    case "CANCELED":
        System.out.println("Order is Cancelled");
        break;
    case "REPLACE":
        System.out.println("Order is replaced successfully");
        break;
    case "FILLED":
        System.out.println("Order is filled");
        break;
    default:
        System.out.println("Invalid");
}

3. Automatic Resource Management

DB컨넥션이나 파일스트림 등을 open 했을 때 예기치 못한 오류 발생시 정상적인 종료를 위해 finally 블럭안에서 close 처리를 해주었는데요. 이로 인해 항상 불필요한 코드를 작성해줘야 했습니다. 요즘에야 DB컨넥션 반납을 프레임워크단에서 잘 처리해주지만 그렇지 않던 시절에 개발자 실수로 컨넥션 close 코드가 누락 되었을 경우엔 컨넥션 반환이 제때 이루어지지 않아 컨넥션풀이 바닥나는 사고도 많았죠.

JDK 7 이전

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static void main(String args[]) {
    FileInputStream fin = null;
    BufferedReader br = null;
    try {
        fin = new FileInputStream("info.xml");
        br = new BufferedReader(new InputStreamReader(fin));
        if (br.ready()) {
            String line1 = br.readLine();
            System.out.println(line1);
        }
    } catch (FileNotFoundException ex) {
        System.out.println("Info.xml is not found");
    } catch (IOException ex) {
        System.out.println("Can't read the file");
    } finally {
        try {
            if (fin != null)
                fin.close();
            if (br != null)
                br.close();
        } catch (IOException ie) {
            System.out.println("Failed to close files");
        }
    }
}

하지만 Java7에서는 try with resource 구문이 추가되어 자동으로 resource들을 close 해줍니다. 물론 공짜는 아니고 AutoClosable, Closeable 인터페이스를 구현한 경우 try(resource)내의 resource들에 대해 close()를 수행해줍니다. 기본적으로 Java7의 Streams, Files, Socket, DB Connection 등은 해당 인터페이스를 구현하고 있습니다.

JDK 7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String args[]) {
    try (FileInputStream fin = new FileInputStream("info.xml");
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    fin));) {
        if (br.ready()) {
            String line1 = br.readLine();
            System.out.println(line1);
        }
    } catch (FileNotFoundException ex) {
        System.out.println("Info.xml is not found");
    } catch (IOException ex) {
        System.out.println("Can't read the file");
    }
}

참 간단해졌죠? Java7에서는 Boiler Plate Code들이 많이 줄어들어 깔끔한 느낌이네요.

4. Fork/Join Framework

fork/join 프레임워크는 멀티프로세서의 성능을 이용할 수 있는 ExecutorService 인터페이스의 구현체입니다. 반복적으로 작은 조각으로 작업을 나누어 수행 할 수 있게 설계 되었습니다. 목표는 어플리케이션의 성능을 향상 시키기 위해 가능한 모든 프로세세를 이용하는 것입니다. ExecutorServcie를 구현함으로써 fork/join 프레임워크는 Thread Pool안의 Worker Thread에게 작업들을 분배합니다. fork/join 프레임워크는 Produce-Consumer 알고리즘과는 매우 다른 work-stealing 알고리즘을 이용합니다. 할 작업이 없는 Worker Thread는 아직 바쁜 다른 Thread의 작업을 훔쳐 올 수 있습니다. fork/join 프레임워크의 핵심은 AbstractExecutorService 클래스를 구현한 ForkJoinPool 클래스입니다. ForkJoinPool은 핵심적인 work-stealing 알고리즘을 구현하고 ForkJoinTask 프로세스들을 실행 할 수 있습니다. RecursiveTask(결과를 반환할 수 있는) 또는 RecursiveAction 같은 ForkJoinTask 하위 클래스를 랩핑할 수 있습니다. (요건 다음 포스팅에서 상세히 다뤄볼까합니다.)

5. Underscore in Numeric literal

숫자형(정수,실수)에 _(underscore) 문자열을 사용 할 수 있습니다. 금융권 등에서 큰 숫자들을 다룰 경우 가독성 향상에 도움이 되겠죠?

1
2
3
4
5
int billion = 1_000_000_000; // 10^9
long creditCardNumber = 1234_4567_8901_2345L; //16 digit number
long ssn = 777_99_8888L;
double pi = 3.1415_9265;
float pif = 3.14_15_92_65f;

_ 위치가 다음과 같을 경우엔 컴파일 에러가 발생하니 주의해야합니다.

1
2
3
double pi = 3._1415_9265; // 소수점 뒤에 _ 붙일 경우
long creditcardNum = 1234_4567_8901_2345_L; // 숫자 끝에 _ 붙일 경우
long ssn = _777_99_8888L; // 숫자 시작에 _ 붙일 경우

6. Catching Multiple Exception Type in Single Catch Block

단일 catch 블럭에서 여러개의 Exception 처리가 가능해졌습니다. (Multi-Catch 구문 지원) JDK7 이전에는 2개의 Exception을 처리하기 위해서는 2개의 catch 블럭이 필요했었죠.

JDK 7 이전

1
2
3
4
5
6
7
try {
    //......
} catch(ClassNotFoundException ex) {
    ex.printStackTrace();
} catch(SQLException ex) {
    ex.printStackTrace();
}

JDK 7

1
2
3
4
5
try {
    //......
} catch (ClassNotFoundException|SQLException ex) {
   ex.printStackTrace();
}

단, Multi-Catch 구문 사용시 다음과 같이 하위클래스 관계라면 컴파일 에러가 발생하므로 주의하세요.

1
2
3
4
5
6
7
8
try {
    //...... }
catch (FileNotFoundException | IOException ex) {
    ex.printStackTrace();
}
 
Alternatives in a multi-catch statement cannot be related by sub classing, it will throw error at compile time :
java.io.FileNotFoundException is a subclass of alternative java.io.IOException at Test.main(Test.java:18)

7. Binary Literals with Prefix “0b”

숫자형에 ‘0B’ 또는 ‘0b’를 앞에 붙임으로써 이진법 표현이 가능합니다. (8진법은 ‘0’, 16진법은 ‘0X’ 또는 ‘0x’)

1
2
int mask = 0b01010000101;
int binary = 0B0101_0000_1010_0010_1101_0000_1010_0010;    // _를 이용한 가독성 향상!

8. Java NIO 2.0

JDK7에서 java.nio.file 패키지를 선보였는데요. 기본파일시스템에 접근도 가능하고 다양한 파일I/O 기능도 제공합니다. 예를 들면 파일을 옮기거나 복사하거나 삭제하는 등의 유용한 메소드들을 제공하며, 파일속성이 hidden인지 체크도 가능합니다. 또한 기본파일시스템에 따라 심볼릭링크나 하드링크도 생성 가능합니다. 와일드카드를 사용한 파일검색도 가능하며 디렉토리의 변경사항을 감시하는 기능도 제공합니다. 어쨋든 외부 라이브러리로 해결했던 많은 일들이 JDK안으로 녹아들었네요.

9. G1 Garbage Collector

G1 Garbage Collection으로 알려진 새로운 Garbage Collector가 추가되었습니다.(G1은 Garbage First의 약자) G1 GC는 Garbage가 가장 많은 영역의 청소를 수행합니다. 이런 수행을 위해 자바 힙메모리 영역을 여러개의 분할된 영역으로 나눕니다. JDK7 이전에서는 new, old, permgen 영역으로 나뉘었는데요. G1 GC는 꽤 새로운 점은 없지만 메모리 집중적인 어플리케이션에 더 큰 throughput을 제공합니다.

10. More Precise Rethrowing of Exception

다음 예제를 보면 try 블럭안에서 ParseException, IOException의 Checked Exception이 발생 할 수 있습니다. 각각의 Exception을 처리하기 위해 Multi-Catch 또는 다중 Catch 문으로 예외처리를 할 수 있지만 예제에서는 최상위 클래스인 Exception으로 처리하였습니다. catch 구문에서 발생한 예외를 상위 메소드로 전달하기 위해 throw 할 경우 메소드 선언부에 해당 예외를 선언해주어야하는데요.

JDK7 이전 버젼에서는 다음 예처럼 catch 구문내에서 선언한 예외 유형만 던질 수 있었습니다. (Exception 클래스),

1
2
3
4
5
6
7
8
9
public void obscure() throws Exception {
    try {
        new FileInputStream("abc.txt").read();
        new SimpleDateFormat("ddMMyyyy").parse("12-03-2014");
    } catch (Exception ex) {
        System.out.println("Caught exception: " + ex.getMessage());
        throw ex;
    }
}

하지만 JDK7에서는 좀 더 정확하게 발생한 Exception을 전달할 수 있습니다. (ParseException, IOException 클래스) 물론 이전과 같이 throws Exception으로 처리할 수도 있지만 메소드를 호출한 쪽에 좀 더 정확한 예외를 던져주는게 좋겠죠?

1
2
3
4
5
6
7
8
9
public void precise() throws ParseException, IOException {
    try {
        new FileInputStream("abc.txt").read();
        new SimpleDateFormat("ddMMyyyy").parse("12-03-2014");
    } catch (Exception ex) {
        System.out.println("Caught exception: " + ex.getMessage());
        throw ex;
    }
}

참고)
10 jdk7 features
http://javarevisited.blogspot.kr/2014/04/10-jdk-7-features-to-revisit-before-you.html

diamond operator
http://www.javaworld.com/article/2074080/core-java/jdk-7–the-diamond-operator.html
http://java.dzone.com/announcements/java-7-do-we-really-need

fork/join framework
http://javarevisited.blogspot.kr/2011/09/fork-join-task-java7-tutorial.html
http://www.oracle.com/technetwork/articles/java/fork-join-422606.html

 

 

퍼온 url : http://www.jpstory.net/2014/06/java-7-features/

'Java & Html' 카테고리의 다른 글

JSP 커스텀 태그(Custom Tag)  (0) 2015.07.07
java 1.8 특징  (0) 2015.06.29
DB컬럼을 빈값으로 만들기  (0) 2015.04.09
Java - 메일 발송  (0) 2015.01.29
[spring] log4j 설정 및 사용법  (0) 2014.11.19