자바의 신 제 2권을 읽고, 각 자바 버전별로 달라진 점을 아는 것도 좋을 것 같아 각 버전별로 추가/ 변경된 부분에 대해 알아보기로 하였다. 우선 자바 7부터 시작해보기로 하자!


Java 7에서 변경된 부분

자바 6에서 자바7로 변경되며 기능이 개선된 부분은 아래와 같다.

숫자 표시 방법 보완

2진수 형태로 숫자를 표현하는 방법과, 1000단위등에 콤마를 붙일 수 있게 되었다.

package f.number;

public class JDK7Numbers {
    public static void main(String[] args) {
        JDK7Numbers jdk7Numbers = new JDK7Numbers();
        jdk7Numbers.jdk7();
        jdk7Numbers.jdk7Underscore();
    }

    private void jdk7() {
        // Java 6에서는 불가하다
        int binaryCal = 0b10001010010;
        System.out.println(binaryCal);
    }

    private void jdk7Underscore(){
        int binaryVal= 0b0100_0101_0010;
        int million = 1_000_000; //개발자가 확인용으로 쓴다. 
        System.out.println(binaryVal);
        System.out.println(million);
    }
}

switch 문장 확장

Java 6까지는 switch-case문에 정수형만 사용할 수 있었다. 그러나, Java 7부터는 switch문에 String도 사용 할 수 있다!

package f.switchcase;

public class JDK7Switch {
    public static void main(String[] args) {
        JDK7Switch jdk7Switch = new JDK7Switch();
        System.out.println(jdk7Switch.salaryIncreaseAmount("Engineer"));
    }

    private double salaryIncreaseAmount(String employeeLevel) {
        switch(employeeLevel){
            case "CEO":
                return 10.0;
            case "Manager" : return 15.0;
            case "Engineer":
            case "Developer":
                return 100.0;
            case"Desigener" :
            case "Planner" :
                return 20.0;
        }
        return 0.0;
    }
}

주의 : String 문자열이 null일 경우, NullPointerException이 발생 할 수 있다.

제네릭을 쉽게 다루는 Diamond

이전에 제네릭 사용시, 다음과 같이 생성자에도 해당 타입을 명시해주었다.

HashMap<String, Integer> map = new HashMap<String, Integer>();
Map<String, List<String>> map2 = new HashMap<String, List<String>>();

하지만, Java 7 부터는 생성자에 일일히 타입을 명시할 필요가 없어졌다. 아래와 같이 말이다.

HashMap<String, Integer> map = new HashMap<>();
Map<String, List<String>> map2 = new HashMap<>();

예외 처리시 다중 처리 기능

이전에는 try-catch 처리시, 여러 예외 상황이 발생하였을 경우, 아래와 같이 catch 구문을 여러개 작성하여 예외를 처리해주어야 했다.

package f.trycatch;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class TryWithResource {
    public void scanFile(String fileName, String encoding) {
        Scanner scanner=null;
        try{
            scanner = new Scanner(new File(fileName), encoding);
            System.out.println(scanner.nextLine());
        } catch(IllegalArgumentException iae){
            iae.printStackTrace();
        } catch (FileNotFoundException ffe) {
            ffe.printStackTrace();
        } catch(NullPointerException npe){
            npe.printStackTrace();
        } catch(Exception e){
            e.printStackTrace();
        } finally {
            if(scanner != null) {
                scanner.close();
            }
        }
    }
}

이렇게 가독성 낮은 코드를 보완하고, 마지막에 가서 굳이 close()하지 않아도 되도록 java 7에서는 아래와 같은 방식을 지원한다.

public void newScanFileTryWithResource(String fileName, String encoding){
        try(Scanner scanner = new Scanner(new File(fileName), encoding)){
            System.out.println(scanner.nextLine());
        } catch(IllegalArgumentException | FileNotFoundException | NullPointerException exception){
            exception.printStackTrace();
        }
    }

catch구문에서 | 를 이용해서 여러 예외를 한 번에 처리할 수 있도록 해주었고, 리소스와 함께 처리하는 try-with-resource를 지원한다. AutoCloseable인터페이스를 구현하는 모든 클래스들은 위와 같이 사용하면 close()를 작성해줄 필요가 없다. 이를 위해서는 try 블록 시작부분에 소괄호 안에 예외가 발생할 수 있는 객체를 입력해주어야 한다. 두 개 이상 입력해야 할 경우, 세미클론으로 선언해주자.


Java 7에서 추가된 부분

Fork/Join

Fork/Join이라는 것은 어떤 계산 작업을 할 때, “여러 개로 나누어 계산한 후 결과를 모으는 작업”을 의미한다. 즉, Fork는 여러 개로 나누는 것을 말하고, Join은 나누어서 작업한 결과를 모으는 것을 의미한다. 이 Fork/Join은 단순하게 작업을 쪼개고 그 결과를 받는 단순한 작업만 포함하지 않는다. Work stealing이라는 개념이 포함되어있다. Work stealing이란, 일정한 쓰레드를 유지하고, 쓰레드마다 독립적인 작업 큐를 관리해, 하나의 쓰레드 큐가 비게 되면 다르 쓰레드에서 task를 훔쳐오도록 해 효율적으로 동작하는 방식이다.

Fork/Join작업의 기본 수행 개념은 아래와 같다.

if(작업의 단위가 충분히 작을 경우) {
 	해당 작업을 수행
} else {
	작업을 반으로 쪼개어  개의 작업으로 나눔
	 작업을 동시에 실행시키고,  작업이 끝날 때까지 결과를 기다림
}

이 작업은 보통 회귀적으로 실행되며, java.util.concurrent 패키지의 ResersiveActionResersiveTask라는 추상클래스를 사용하여 작업한다.

NIO2

기존 Java IO는 운영체제나 다중파일 시스템에서 동일하게 적용하기 어렵다. 예기치 않게 발생된 delete 혹은 rename 메소드가 그런 케이스이다. IO에서 불편한 점을 보다 개선하기 위해 NIO2를 제공한다.


참고 자료

  1. 자바의 신 제 2권 30장~31장

oksusutea's blog

꾸준히 기록하려고 만든 블로그