1. Java 7
Type Inference (타입 추론)
<7 버전 이전>
List<String> list = new ArrayList<String>();
<7 버전 이후>
List<String> list = new ArrayList<>();
Switch 문 문자열 case * 말 그대로 Switch ~ Case 문에 문자열이 가능해졌다.
Automatic Resource Management * 보통 DB연동이나 파일 스트림 같이 open하고 close를 해주어야하는 경우 try ~ catch문 다음에 finally에 close를 해주게 되는데 7부터는 finally에 close를 쓰지않게 되면 알아서 try 마지막에 close 하게된다.
Catching Multiple Exception Type in Single Catch Block * 7 이후부터 멀티 catch가 가능해졌다.
catch (IOException ioex) {
System.out.println("Error in System");
}catch (SQLException sqlex) {
System.out.println("Error in System");
}
2. Java 8
람다 표현식(Lambda Expression)
- 메소드를 하나의 식으로 표현한 것이며, 식별자 없이 실행할 수 있는 함수 표현식을 뜻하고,
따라서 익명 함수(anonymous function)라고도 부릅니다.
- 컴파일러(JIT 인터프리터)한테 실질적 구현을 시키는 방식
new Thread(new Runnable() {
public void run() {
System.out.println("전통적인 방식의 일회용 스레드 생성");
}
}).start();
new Thread(()->{
System.out.println("람다 표현식을 사용한 일회용 스레드 생성");
}).start();
void m() {
String tFlag = request.getParameter("tFlag");
tFlag = (tFlag == null) ? "" : tFlag;
}
String tFlag = Optional.ofNullable(request.getParameter("tFlag")).orElse("");
String tFlag = request.getParameterMap().getOrDefault("tFlag", "")
interface 클래스에 구현체 작성 가능 * default와 static 키워드를 사용해서 구현 메소드를 interface에 작성할 수 있게 되었다.
Optional Optional은 null이 될 수도 있는 객체를 감싸는 일종의 래퍼 클래스이며, null체크를 최대한 하지않고도 코딩하게끔 나온 클래스 Optional<>로 객체를 생성하고, 메서드로 null 검사 및 수행 * Optional 객체의 생성 : of() 메소드나 ofNullable() 메소드를 사용하여 Optional 객체를 생성하고 of() 메소드는 null이 아닌 명시된 값을 가지는 Optional 객체를 반환 만약 of() 메소드를 통해 생성된 Optional 객체에 null이 저장되면 NullPointerException 예외가 발생하며, null이 될 가능성이 있다면 ofNullable() 메소드를 사용하여 Optional 객체를 생성하여 사용. (ofNullable() 메소드는 명시된 값이 null이 아니면 명시된 값을 가지는 Optional 객체를 반환하며, 명시된 값이 null이면 비어있는 Optional 객체를 반환)
Optional<String> opt = Optional.ofNullable("자바 Optional 객체");
System.out.println(opt.get());
- Optional 객체에 접근 : get() 메소드를 사용하면 Optional 객체에 저장된 값에 접근할 수 있습니다. 만약 Optional 객체에 저장된 값이 null이면, NoSuchElementException 예외가 발생합니다. 따라서 get() 메소드를 호출하기 전에 isPresent() 메소드를 사용하여 Optional 객체에 저장된 값이 null인지 아닌지를 먼저 확인한 후 호출하는 것이 좋습니다.
ptional<String> opt = Optional.ofNullable("자바 Optional 객체");
if(opt.isPresent()) {
System.out.println(opt.get());
}
- 메소드를 사용하여 null 대신에 대체할 값을 지정할 수도 있습니다.
- orElse() 메소드 : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환함.
- orElseGet() 메소드 : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결괏값을 반환함.
- orElseThrow() 메소드 : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생시킴.
empty() 메소드는 Optional 객체를 null로 초기화
Optional<String> opt = Optional.empty(); // Optional를 null로 초기화함.
System.out.println(opt.orElse("빈 Optional 객체"));
System.out.println(opt.orElseGet(String::new));
public Family method1() {
Family family = new Family();
//...
family.setCount(3);
//...
return family;
}
public void test(){
//해당 객체의 null을 검사할 수 있는 wrapper 클래스를 만든다.
Optional<Family> optFamily = Optional.ofNullable(method1());
//ifPresent로 직접 해당객체가 null이 아닐 때 action을 줄 수 있고
optFamily.ifPresent(x->System.out.println(x.getCount()));
//orElse로 받아온 객체가 null일 때는 빈 객체를 만들어서 리턴받을 수도 있다.
Family family = optFamily.orElse(new Family());
}
java.time 패키지 Joda-Time 라이브러리를 발전시킨 새로운 날짜와 시간 API인 java.time 패키지를 제공합니다. 기존에 사용되던 Calendar 클래스의 단점을 보완하였으며,해당 패키지에 속하는 모든 클래스의 인스턴스는 불변 객체(immutable object)로 생성됩니다.(즉, java.time 패키지에 포함되는 클래스의 메소드들은 모두 새로운 객체를 생성하여 반환) Java SE 8부터 제공되는 java.time 패키지에는 자바에서 날짜와 시간을 다루는 데 사용되는 필수 클래스들이 포함되어 있으며,다음과 같은 다양한 기능을 하는 하위 패키지를 포함하고 있습니다. 1. java.time.chrono : ISO-8601에 정의된 표준 달력 이외의 달력 시스템을 사용할 때 필요한 클래스들 2. java.time.format : 날짜와 시간에 대한 데이터를 구문분석하고 형식화하는 데 사용되는 클래스들 3. java.time.temporal : 날짜와 시간에 대한 데이터를 연산하는 데 사용되는 보조 클래스들 4. java.time.zone : 타임 존(time-zone)과 관련된 클래스들 java.time 패키지의 구성 클래스 기존의 Calendar 클래스는 날짜와 시간을 한번에 표현했지만, java.time 패키지에서는 별도로 구분하여 처리합니다. LocalDate 클래스는 날짜를 표현할 때 사용하며, LocalTime 클래스는 시간을 표현할 때 사용합니다. 또한, 기존의 Calendar 클래스처럼 날짜와 시간을 한 번에 표현하고 싶을 때는 LocalDateTime 클래스를 사용합니다.
ex) 사용법
LocalDate currentDate = LocalDate.now(); // 컴퓨터의 현재 날짜 정보 2018-07-26
currentDate.
getYear(); 2019
getMonth(); (Month 열거값나옴 JANUARY, FEBRUARY)
getMonthValue(); 월(1,2,3,...)
getDayOfYear(); 년의 몇 번째 일
getDayOfMonth(); 월의 몇번째 일
getDateOfWeek();요일(MONDAY, TUESDAY,...)
isLeapYear(); 윤년여부
LocalTime currentTime = LocalTime.now(); // 컴퓨터의 현재 시간 정보. 결과 : 16:24:02.408
LocalTime targetTime = LocalTime.of(int hour, int minute, int second, int nanoOfSecond);
int getHour() 시간
int getMinute() 분
int getSecond() 초
int getNano() 나노초
LocalDateTime 시간,날짜 동시에 필요할 때 사용.
LocalDateTime currentDateTime = LocalDateTime.now(); // 컴퓨터의 현재 날짜와 시간 정보. 결과 : 2018-07-26T16:34:24.757
LocalDateTime targetDateTime = LocalDateTime.of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond);
ZonedDateTime utcDateTime = ZonedDateTime.now(ZoneId.of("UTC"));
ZonedDateTime seoulDateTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
ex) 날짜/시간 변환(TimeStamp와 format으로 바꾸는 것이 유용)
LocalDate -> String
LocalDate.of(2020, 12, 12).format(DateTimeFormatter.BASIC_ISO_DATE); // 20201212
LocalDateTime -> String
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 2018-07-26 00:42:24
LocalDateTime -> java.util.Date
Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()); //Thu Jul 26 01:00:30 KST 2018
LocalDate -> java.sql.Date
Date.valueOf(LocalDate.of(2015, 5, 5)); // 2018-07-26
LocalDateTime -> java.sql.Timestamp
Timestamp.valueOf(LocalDateTime.now()); // 2018-07-26 01:06:55.323
String -> LocalDate
LocalDate.parse("2002-05-09"); // 2002-05-09
LocalDate.parse("20081004", DateTimeFormatter.BASIC_ISO_DATE); // 2008-10-04
String -> LocalDateTime
LocalDateTime.parse("2007-12-03T10:15:30"); // 2007-12-03T10:15:30
LocalDateTime.parse("2010-11-25 12:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 2010-11-25T12:30
java.util.Date -> LocalDateTime
LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault()); // 2018-07-26T01:16:46.755
java.sql.Date -> LocalDate
new Date(System.currentTimeMillis()).toLocalDate(); // 2018-07-26
java.sql.Timestamp -> LocalDateTime
new Timestamp(System.currentTimeMillis()).toLocalDateTime(); // 2018-07-26T01:20:07.364
LocalDateTime -> LocalDate
LocalDate.from(LocalDateTime.now()); // 2018-07-26
LocalDate -> LocalDateTime
LocalDate.now().atTime(2, 30); // 2018-07-26T02:30
스트림 API(Stream API) * 스트림 API는 데이터를 추상화하여 다루므로, 다양한 방식으로 저장된 데이터를 읽고 쓰기 위한 공통된 방법을 제공합니다. 따라서 스트림 API를 이용하면 배열이나 컬렉션뿐만 아니라 파일에 저장된 데이터도 모두 같은 방법으로 다룰 수 있습니다.
String[] arr = new String[]{"넷", "둘", "셋", "하나"};
// 배열에서 스트림 생성
Stream<String> stream1 = Arrays.stream(arr);
stream1.forEach(e -> System.out.print(e + " "));
System.out.println();
// 배열의 특정 부분만을 이용한 스트림 생성
Stream<String> stream2 = Arrays.stream(arr, 1, 3);
stream2.forEach(e -> System.out.print(e + " "));
GC 성능 대폭 개선 * Java 8부터는 메모리 누수를 일으키던 메소드 영역의 PermGen Area를 제거하여 static 인스턴스와 리터럴 문자열도 GC의 대상이 되도록 바뀌었으며, 클래스, 메소드,배열의 메타 정보는 동적 리사이징이 가능한 Metaspace로 이동시켜 시스템 힙 영역에 저장된다. 덕분에 JVM 힙 영역의 공간이 늘어나고 PermGen Area를 스캔/삭제할 필요가 없어져 GC의 성능이 대폭 향상되었다.
3. Java 9
인터페이스 내에 private 구현체 가능
interface NewInterface {
private static String staticPrivate() {
return "static private";
}
private String instancePrivate() {
return "instance private";
}
default void check() {
String result = staticPrivate();
NewInterface newIf = new NewInterface() {
// anonymous class
};
result = newIf.instancePrivate();
}
}
CompletableFuthre API 개선
ex) 50초후에 새로운 Executor 생성(웹서버 구현)
Executor executor = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
HTTP2 클라이언트(동기/비동기 지원가능)
// 동기 호출
HttpResponse response = HttpRequest
.create(new URI("http://www.ocado.com"))
.body(noBody())
.GET().send();
int responseCode = response.responseCode();
String responseBody = response.body(asString());
System.out.println(responseBody);
// 비동기 호출
HttpRequest request = HttpRequest
.create(new URI("http://www.ocado.com"))
.body(noBody())
.GET();
CompletableFuture<HttpResponse> future = request.sendAsync();
Thread.sleep(10);
If (!future.isDone()) {
future.cancel(true);
System.err.println("timeout");
return;
}
HttpResponse response = future.get();
모듈시스템 등장(jigsaw) - 기존 jar방식을 개선하기위해 등장함
4. Java 10
Local Variable Type Inference(var 사용) * 자료형을 완벽히 숙지한 상태에서 사용한다면 유용하게 쓰일 문법ex.1)
<Java 10 이전>
Map<String,Integer> x = new HashMap<>();
<Java 10>
var x = new HashMap<String,Integer>();
ex.2)
var list = new ArrayList<String>();
var stream = list.stream();
var numbers = List.of(1, 2, 3, 4, 5);
ex.3)
Java 10 이전
int age = 10; // int형 변수 선언
String name ="aa" // String 문자열 선언
Aa aa = new Aa(); // 객체생성
Java 10
var age = 10;// var는 정수형을 나타낼 수 있는 타입으로 결정
var name = "aa";// var는 문자열을 나타낼 수 있는 타입인 String으로 결정
var aa = new Aa(); // Aa 라는 클래스 타입으로 var를 추론 가능
※ 주의사항
- 초기값이 결정되지 않는다면 추론이 불가능하다.
ex)
var age; <-- 오류 상황
var name; <-- 오류 상황
JVM heap 영역을 NVDIMM (비휘발성 NAND 플래시 메모리) 혹은 사용자 지정과 같은 대체 메모리 장치에 할당 가능 자바 HEAP을 NVDIMM에 세팅가능하게 됨. 이 기능은 새로 추가된 옵션인 -XX:AllocateHeapAt=를 이용해 사용할 수 있습니다.(별로 쓸모없는 대상 판단)