13. 자바 8의 특징
1. 람다 표현식(Lambda Expression)
: 메서드로 전달될 수 있는 익명 함수를 단순한 문법으로 표기한 것
2. 함수형 인터페이스(Functional Interface)
: 추상 메서드가 오직 하나인 인터페이스
-> 단일 추상 메서드를 가지는 인터페이스
- 여러 개의 Default 메소드와 Static 메소드가 있어도 함수형 인터페이스로 취급
@FunctionalInterface
public interface Math {
public int Callc(int first, int secont);
}
public class Main {
public static void main(String[] args) {
Math plusLambda = ((first, secont) -> first + secont);
System.out.println(plusLambda.Callc(4,2));
Math minusLambda = new Math() {
@Override
public int Callc(int first, int secont) {
return first - secont;
}
};
System.out.println(minusLambda.Callc(4,2));
}
}
3. 디폴트 메소드(Default Method)
: 인터페이스 내에서 구현이 가능한 메소드
- static 메소드도 추가로 구현이 가능함
- 이전 버전에서는 인터페이스 내에서 추상 메소드만을 선언할 수 있었지만, static, default 메소드를 구현할 수 있게 됨
4. 스트림(Stream)
: 컬렉션과 배열의 데이터 처리를 도와주는 기술
- 이전 버전에서는 데이터를 처리하는 방법은 for문, for-each문을 돌면서 데이터를 가공
- 간단한 경우라면 상관없지만, 로직이 복합한 경우
-> 코드 양이 많아져 로직이 섞이고 쉽게 이해를 할 수 없는 상황이 발생
- 이러한 문제점을 해결하기 위해서 나온 기술
- 병렬 처리가 가능함
5. 옵셔널(Optional)
: 존재할 수도 있지만, 안할 수도 있는 객체, 즉, null이 될 수도 있는 객체를 감싸고 있는 일종의 래퍼 클래스
- NullPointerException을 방지하기 위해서 null 대신으로 나온 클래스
- Optional을 사용하면 NullPointerException을 유발할 수 있는 Null을 직접 다루지 않아도 됨
1) 기본 사용법
- 제너릭을 제공하기 때문에 변수를 선언할 때, 명기한 타입 파라미터에 따라서 감쌀 수 있는 객체의 타입이 결정됨
- 변수 명은 클래스 이름을 사용하기도 하지만, "maybe"나 "opt"와 같은 접두어를 붙여서 사용하는 게 Optional 클래스를 명확히 나타냄
2) 객체 생성하기
- Optional<Member> maybeMember = Optional.empty();
- null을 담고 있는 객체를 생성
- 클래스 내부적으로 미리 생성해 놓은 싱글턴 인스턴스임
- Optional<Member> maybeMember = Optional.of(aMember);
- null이 아닌 객체를 생성
- null이 넘어올 경우, NPE을 던지기 때문에 주의
- Optional<Member> maybeMember = Optional.ofNullable(aMember);
Optional<Member> maybeNotMember = Optional.ofNullable(null);- null인지 아닌지 모르는 객체를 생성할 때 사용
- null을 넣어 생성한 경우, 앞의 empty()함수처럼 비어있는 객체가 생성됨
3) Optional이 담고 있는 객체에 접근하기
- Optional에 null을 가지고 있을 때 다르게 작동하는 함수들에 대해 서술
- get()
- 비어있는 Optional 객체에 대해서 NoSuchElementException을 던짐
- orElse( T other )
- 비어있는 Optional 객체에 대해서 넘어온 인자를 반환
- other은 메서드 호출 전에 무조건 평가됨
- 즉, Optional에 값이 있든 없든 other은 먼저 만들어짐
- orElseGet( Supplier <? extends T> other)
- 비어있는 Optional 객체에 대해서 넘어온 인자를 반환
- Optional이 비어있을 때만 실행됨
- orElseThrow(Supplier <? extends X> exceptionSupplier)
- 비어있는 Optional 객체에 대해서, 넘어온 함수형 인자를 통해 생성된 예외를 던짐
4) Optional의 잘못된 사용
- Optional에는 객체가 null인지를 확인하는 isPresent()라는 메소드가 있음
-> null이면 false, null이 아니면 true를 출력
-> 해당 메소드를 사용하면 Optional을 사용하는 이유가 없음
int length = Optional.ofNullable(getText()).map(String::length).orElse(0);
- 이와 같이 코드를 짜도록 노력해야 함
6. JVM의 변화
- 원래 Permanent Generation Heap(PermG)에는 아래와 같은 정보가 저장되어 있었음
- Class의 메타 데이터 (바이트 코드 포함)
- Method의 메타 데이터
- static 객체, static 상수
- 상수화된 String Object
- Class와 관련된 배열 객체 메타 데이터
- JVM 내부적인 객체들과 JIT의 최적화 정보
=> Permanent Heap은 일정량의 데이터 공간을 필수적으로 가지고 있어야 했음
cf) 메타데이터
: 어떤 데이터가 무엇인지 설명해주는 정보
- EX) 사진 : 데이터, 찍은 날짜 : 메타데이터
- Class와 Method의 메타데이터와 여러 객체들이 증가함으로 메모리양이 저장 공간보다 늘어나 OOM(Out Of Memory Error)가 발생하는 문제점이 발생함
- JVM에서 PermG 부분이 삭제되고, Native Memory 부분에 Metaspace가 추가 됨
- 기존의 PermG에 있었던 데이터는 아래와 같이 변경됨
- MetaSpace에 저장되는 데이터
- Class의 메타데이터(바이트 코드도 포함)
- Method의 메타데이터
- Class와 관련된 배열 객체 메타데이터
- JVM 내부적인 객체들과 JIT의 최적화 정보
- Heap에 저장되는 데이터
- static 객체, static 상수
- 상수화된 String Object
- Heap에 저장되는 데이터는 GC의 대상이 될 수 있게 됨
- Native 영역은 OS 레벨에서 관리해 자동으로 크기를 조절함
=> 개발자가 메모리 영역 확보의 상한을 크게 인식할 필요가 없게 됨
cf) GC가 관리하는 메모리
- 자바는 new 키워드로 객체를 생성 -> Heap 메모리에 저장
- 개발자가 따로 free()로 해제하지 않고 이러한 객체를 GC가 정리해줌
- 참조가 끊긴 객체를 찾음 -> 어떤 객체가 더 이상 코드에서 사용되지 않음
- 쓸모없는 객체를 제거 -> 그 객체가 차지하고 있던 메모리를 해제