사용자 도구

사이트 도구


java:7

Java 7

예외 다중 캐치

try {
  // do something
} catch (Exception1 | Exception2 | Exception3 ex) {
  ex.printStackTrace();
}

바(|)를 통해 여러가지 예외를 한번에 catch 할 수 있다.

try with resource

java.lang.AutoCloseable 인터페이스를 구현한 리소스는 finally 블록에서 명시적으로 close()하지 않아도 자동으로 close()를 무조건 호출 할 수 있게 되었다.

과거에는 finally 블록에서 명시적으로 다음과 같이 close()를 호출해줘야만 리소스를 닫아줄 수 있었다.

// Java7 이전
BufferedReader reader = null;
try {
    reader = new BufferedReader(new FileReader("C:/Windows/system32/drivers/etc/hosts"));
    String line = reader.readLine();
    while (line != null) {
        System.out.println(line);
        line = reader.readLine();
    }
} finally {
    if (reader != null) {
        try {
            reader.close();
        } catch (Exception ex) {
            // ignored
        }
    }
}

위와 같은 코드가 Try With Resource 블록을 사용하면 아래와 같이 된다. catch 블록이 없어도 된다는 사실에 주의.

// Java7
try (BufferedReader reader = new BufferedReader(new FileReader("C:/Windows/system32/drivers/etc/hosts"))) {
    String line = reader.readLine();
    while (line != null) {
        System.out.println(line);
        line = reader.readLine();
    }
}

try () 안에서는 세미콜론으로 구분하여 여러개의 리소스를 생성해도 된다.

예외 다시 던질 때 예외 클래스 자동 판단

catch 절에서 예외를 잡아서 다시 던질 때, Java 7 이전에는 catch 절에서 잡는 타입에 따라 해당 메소드의 throws 절이 결정되었었다.

public static class FirstException extends Exception {
}
 
public static class SecondException extends Exception {
}
 
public static void rethrowException(String msg) throws Exception {
    try {
        switch (msg) {
            case "First":
                throw new FirstException();
            default:
                throw new SecondException();
        }
    } catch (Exception ex) {
        throw ex;
    }
}

즉, rethrowException 메소드는 catch (Exception ex) 때문에 항상 throws Exception으로 선언되어야 했었다. 하지만 Java 7 부터는 try 블록에서 실제로 발생 가능한 예외를 컴파일러가 분석하여, catch 절과 무관하게 throws 할 예외 클래스를 지정할 수 있게 되었다. 다음과 같이 FirstExceptionSecondException을 명시해 주는게 가능해 진다.

public static void rethrowException(String msg) throws FirstException, SecondException {
    try {
        switch (msg) {
            case "First":
                throw new FirstException();
            default:
                throw new SecondException();
        }
    } catch (Exception ex) {
        throw ex;
    }
}

String switch

문자열을 switch/case 구문에 사용할 수 있게 되었다.

Console console = System.console();
 
String value = console.readLine("입력 : ");
switch(value) {
    case "A":
        System.out.println("A");
        break;
    case "B":
        System.out.println("B");
        break;
    case "some":
        System.out.println("some");
        break;
    default:
        System.out.println("Don't know...");
}

Diamond Operator

Generic 객체를 생성할 때 선언이 올바로 되어 있으면 객체 생성 구문에서 제너릭타입을 지정하지 않고 <> 만 사용해도 된다.

public static void main(String[] args) throws Exception {
    // 앞부분의 선언 때문에, 객체 생성 구문에서는 제너릭 타입 지정 불필요
    List<String> strings = new ArrayList<>();
}
 
public static Map<String,Long> getValues() {
    // 메소드 선언의 제너릭타입 지정 때문에, return 문에서도 Diamond Operator 사용 가능
    return new HashMap<>();
}

이진수 지원

byte,short,int,long 형을 0B숫자를 사용해 이진수로 표현할 수 있다. Binary Literals

int binary = 0B10;
System.out.println(binary); // 2
 
binary = 0B11111111;
System.out.println(binary); // 255

숫자에 밑줄 가능

숫자값에 밑줄(_)을 써도 되며 밑줄은 그냥 무시된다. 숫자의 가독성을 높이는데 사용하면 된다.

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 	3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

java.util.Objects 클래스

  • java.util.Objects 클래스의 다양한 정적 메소드들은 코드량을 줄여준다.
  • equals null에 안전한 equals 를 구현한다.

java.nio.file.Files 클래스

  • java.nio.file.Files는 파일 관련한 복사, 경로 관리등 다양한 정적 메소드들을 제공해준다.
  • Java 7 Files에서 자세히 볼 수 있다.

MethodHandles

MethodHandle을 사용하면 메소드를 객체로 전달하는 것이 가능해진다. Vanilla Java: MethodHandle performance in Java 7를 참조하였다.

아래는 multiply 메소드를 MethodHandle 객체로 만든 뒤에 해당 메소드를 호출하는 것을 보여준다.

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
 
public class Java7Test {
 
    public static int multiply(int i, int j) {
        return i * j;
    }
 
    public static void main(String[] args) throws Throwable {
        Lookup lookup = MethodHandles.lookup();
 
        MethodHandle multiply = lookup.findStatic(Java7Test.class, "multiply", MethodType.methodType(int.class, int.class, int.class));
 
        System.out.println(multiply.invoke(5,6)); // multiply(5,6) 호출
 
        // 1번 인자로 4를 미리 지정해둔다.
        MethodHandle quadruple = MethodHandles.insertArguments(multiply, 1, 4);
        System.out.println(quadruple.invoke(5)); // multiply(4,5) 호출
    }
}

ThreadLocalRandom

  • Random을 멀티쓰레드로 접근하면 synchronized 때문에 성능이 저하됨.
  • 쓰레드별로 Random 객체를 따로 생성하는 ThreadLocalRandom을 사용하면 된다.
// 대부분 아래와 같은 형태로 사용하면 된다.
ThreadLocalRandom.current().nextX(...)

기타

참조

java/7.txt · 마지막으로 수정됨: 2018/10/17 17:46 저자 kwon37xi