자바 8 의 새로운 기능 중 하나:optional 클래스

6013 단어 자바
optional 은 null 키워드 에 대한 대체 가 아니 라 null 판정 에 더욱 우아 한 실현 을 제공 합 니 다.
NullPoint Exception 은 모든 자바 개발 자 들 이 겪 은 이상 이 라 고 할 수 있 습 니 다.자바 는 디자인 초기 부터 프로그래머 가 지침 의 고 해 를 벗 어 나 도록 노력 했 지만 지침 은 실제 존재 합 니 다.자바 디자이너 도 지침 을 자바 언어 에서 더욱 간단 하고 쉽게 사용 할 수 있 을 뿐 완전히 제거 할 수 없습니다.그래서 우리 가 일상적으로 볼 수 있 는 키워드null가 생 겼 다.
빈 포인터 이상 은 실행 시 이상 입 니 다.이러한 이상 에 대해 명확 한 처리 전략 이 없다 면 가장 좋 은 실천 은 프로그램 을 일찍 끊 는 것 입 니 다.그러나 많은 장면 에서 개발 자 들 이 구체 적 인 처리 전략 이 없 는 것 이 아니 라 빈 포인터 이상 의 존 재 를 전혀 의식 하지 못 하 는 것 입 니 다.이상 이 정말 발생 할 때 처리 전략 도 간단 합 니 다.이상 이 존재 하 는 곳 에 if 문 구 를 추가 하여 판정 하면 됩 니 다.그러나 이러한 대응 전략 은 우리 의 프로그램 에 점점 더 많은 null 판정 을 하 게 할 것 입 니 다.우 리 는 좋 은 프로그램 설 계 를 알 고 있 습 니 다.코드 에 null 키워드 가 최대한 적 게 나타 나 도록 해 야 합 니 다.자바 8 이 제공 하 는Optional류 는 NullPoint Exception 을 줄 이 는 동시에 코드 의 미관 도 향상 시 켰 다.그러나 우선 우리 가 명확 하 게 해 야 할 것 은 그것 이 null키워드 에 대한 대체 가 아니 라 null 판정 에 더욱 우아 한 실현 을 제공 하여 NullPoint Exception 을 피한다.
직관 감
만약 에 우리 가 문자열 의 길 이 를 되 돌려 야 한다 고 가정 합 니 다.만약 에 제3자 도구 류 를 빌 리 지 않 으 면 우 리 는 호출str.length()방법 이 필요 합 니 다.
if(null == str) { //      
    return 0;
}
return str.length();

옵션 클래스 를 사용 하면 다음 과 같이 실 현 됩 니 다.
return Optional.ofNullable(str).map(String::length).orElse(0);

optional 의 코드 는 상대 적 으로 더욱 간결 합 니 다.코드 의 양 이 많 을 때 우 리 는 null 판정 을 하 는 것 을 잊 기 쉽 지만 optional 류 를 사용 하면 이런 문 제 를 피 할 수 있 습 니 다.
기본 사용
1.대상 생 성
빈 개체 만 들 기
Optional optStr = Optional.empty();

위의 예제 코드 호출empty()방법 은 빈Optional대상 형 을 만 들 었 습 니 다.
생 성 대상:빈 optional 에 방법of()을 제공 하여 비 어 있 는 대상 을 만 드 는 데 사용 할 수 없습니다.이 방법 은 들 어 오 는 매개 변수 가 비어 있 으 면 안 됩 니 다.그렇지 않 으 면 던 지기NullPointException는 다음 과 같 습 니 다.
Optional optStr = Optional.of(str);  //  str null   ,   NullPointException

생 성 대상:들 어 오 는 인자 가 null 값 이 있 는 지 확인 하지 못 하면 optionalofNullable()방법 으로 대상 을 만 들 수 있 습 니 다.들 어 오 는 인자 가 null 값 이 있 는 지 확인 하지 못 하면 빈 대상 을 만 들 수 있 습 니 다.예 는 다음 과 같다.
Optional optStr = Optional.ofNullable(str);  //   str null,        

2.흐름 식 처리
스 트림 처리 도 자바 8 이 우리 에 게 가 져 다 준 중량급 의 새로운 특성 으로 집합 작업 을 더욱 간결 하고 효율 적 으로 만 들 었 습 니 다.다음 자바 8 의 새로운 특성 에 관 한 글 은 유실 처리 에 대해 전면적 인 설명 을 할 것 입 니 다.여기 서 optional 도 두 가지 기본 적 인 유실 처 리 를 제공 했다.맵 과 여과 이다.
시범 을 보이 기 위해 우 리 는 다음 과 같은User종 류 를 설계 했다.
/**
 * @author: zhenchao.Wang 2016-9-24 15:36:56
 */
public class User {

    /**      */
    private long id;

    private String name;

    private int age;

    private Optional phone;

    private Optional email;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //   setter getter
}

휴대 전화 와 메 일 은 한 사람의 필수 가 아니 기 때문에 우 리 는 Optional 정 의 를 이용 합 니 다.
맵:맵 과 flatMap 맵 은 입력 을 다른 형식의 출력 으로 변환 하 는 작업 입 니 다.예 를 들 어 앞의 예 에서 우 리 는 문자열 을 입력 하고 출력 하 는 것 은 문자열 의 길이 입 니 다.이것 이 바로 암시 입 니 다.우 리 는 방법map()을 이용 하여 이 루어 집 니 다.만약 에 우리 가 한 사람의 이름 을 얻 기 를 원한 다 면 우 리 는 다음 과 같이 실현 할 수 있다.
String name = Optional.ofNullable(user).map(User::getName).orElse("no name");

이렇게 하면 사용자 가 비어 있 지 않 을 때 name 을 되 돌려 줍 니 다.그렇지 않 으 면 되 돌려 줍 니 다no name 만약 에 우리 가 위의 방식 으로 phone 이나 email 을 얻 기 를 원한 다 면 위의 방식 을 이용 하면 안 됩 니 다.map 후에 돌아 온 것 은 optional 이기 때 문 입 니 다.우 리 는 이런 것 을 optional 내장 이 라 고 부 릅 니 다.우 리 는 map 에서 한 번 에 우리 가 원 하 는 결 과 를 얻 을 수 있 습 니 다.
long phone = optUser.map(User::getPhone).map(Optional::get).orElse(-1L);

사실 이때 더 좋 은 방법 은 flatMap 을 이용 하여 우리 가 원 하 는 결 과 를 얻 는 것 이다.
long phone = optUser.flatMap(User::getPhone).orElse(-1L);

flapMap 은 방법 이 되 돌아 오 는 각 흐름 을 하나의 흐름 으로 편평 하 게 만 들 수 있 으 며,구체 적 으로 다음 스 트림 처 리 를 전문 으로 하 는 글 에서 자세히 말 할 수 있 습 니 다.
여과:fliter filiter,말 그대로 여과 작업 입 니 다.우 리 는 여과 작업 을 매개 변수 로 이 방법 에 전달 하여 여과 목적 을 실현 할 수 있 습 니 다.18 세 이상 의 성인 을 선별 하고 자 하 는 경우 다음 과 같이 실현 할 수 있 습 니 다.
optUser.filter(u -> u.getAge() >= 18).ifPresent(u -> System.out.println("Adult:" + u));

3.묵인 행위
기본 행 위 는 optional 이 조건 을 만족 시 키 지 못 할 때 실행 하 는 동작 입 니 다.예 를 들 어 위의 예 에서 우리 가 사용 하 는orElse()은 기본 동작 입 니 다.optional 대상 이 비어 있 을 때 특정한 조작 을 수행 하 는 데 사 용 됩 니 다.물론 일부 기본 동작 은 조건 을 만족 시 키 는 대상 이 존재 할 때 실 행 됩 니 다.
get()get 은 변수의 값 을 가 져 오 는 데 사용 되 지만 변수 가 존재 하지 않 을 때 던 집 니 다NoSuchElementException.따라서 변수 가 존재 하 는 지 확인 하지 않 으 면 사용 하 는 것 을 권장 하지 않 습 니 다.
orElse(T other)는 optional 변수 가 주어진 조건 에 만족 하지 않 을 때 orElse 를 실행 합 니 다.예 를 들 어 앞에서 str 가 null 일 때 0 을 되 돌려 줍 니 다.
orElseGet(Supplier extends X>expection Supplier)조건 이 성립 되 지 않 을 경우 간단 한 리 턴 작업 이 아 닌 상대 적 으로 복잡 한 논 리 를 수행 해 야 할 경우 orElseGet 을 사용 하여 구현 할 수 있 습 니 다.
long phone = optUser.map(User::getPhone).map(Optional::get).orElseGet(() -> {
    // do something here
    return -1L;
});

orElseThrow(Supplier extends X>expection Supplier)는 get()방법 과 유사 하 며 조건 이 충족 되 지 않 을 때 이상 을 되 돌려 줍 니 다.그러나 여기 서 되 돌아 오 는 이상 유형 을 지정 할 수 있 습 니 다.
ifPresent(Consumer super T>)가 조건 을 만족 시 킬 때 들 어 오 는 매개 변수 화 작업 을 수행 합 니 다.
주의사항
optional 은 final 클래스 로 어떠한 인터페이스 도 실현 되 지 않 았 기 때문에 우리 가 이러한 포장 정의 류 의 속성 을 이용 할 때 우리 가 정의 하 는 클래스 가 직렬 화 된 수요 가 있다 면 optional 이 Serializable 인 터 페 이 스 를 실현 하지 못 했 기 때문에 이 럴 때 직렬 화 작업 을 수행 하면 문제 가 생 길 수 있 습 니 다.
public class User implements Serializable{

    /**      */
    private long id;

    private String name;

    private int age;

    private Optional phone;  //      

    private Optional email;  //      

그러나 우 리 는 다음 과 같은 대체 전략 을 사용 할 수 있다.
private long phone;

public Optional getPhone() {
    return Optional.ofNullable(this.phone);
}

Optional 은 디자인 할 때 클래스 필드 로 사용 하 는 것 을 고려 하지 않 은 것 같 습 니 다.

좋은 웹페이지 즐겨찾기