소개
NPE (NullPointerException)는 디버깅 프로그램에서 가장 일반적인 예외입니다. Google 은이 방법이 NULL 또는 새 빈 개체를 반환 해야하는지 여부에 대해 많은 논의를 가지고 있습니다.
기사가 시작될 때 NPE 문제에 대해 먼저 이야기 해 봅시다. NPE 문제는 우리가 종종 개발에 직면하는 NullPointerException입니다. 두 개의 클래스가 있다고 가정하고 UML 클래스 다이어그램이 다음 그림에 표시됩니다.
이 경우 다음 코드가 있습니다
user.getAddress (). getProvince ();
이러한 글쓰기 방식은 사용자가 NULL 일 때 NULLPOINETEREXCEPTION을보고 할 수 있습니다. 이 문제를 해결하기 위해 다음과 같은 글쓰기 방법이 채택됩니다.
if (user! = null) {주소 주소 = user.getAddress (); if (address! = null) {String province = address.getProvince (); }}이 글쓰기 스타일은 비교적 추악합니다. 위의 못생긴 글쓰기 스타일을 피하기 위해 못생긴 디자인이 우아하게됩니다. Java8 은이 쓰기 방법을 최적화하기위한 옵션 클래스를 제공하며 다음 텍스트 섹션은 자세히 설명됩니다.
API 소개
먼저 API를 소개하겠습니다. 다른 기사와 달리이 기사는 유추 메소드를 채택하고 소스 코드를 결합합니다. 다른 기사와 달리 각 API 목록은 사람들이 핵심 포인트를 찾을 수 없습니다.
(1) 선택 사항 (t 값), empty (), of (t 값), ofnullable (t 값)
이 네 가지 기능에는 상관 관계가 있으므로 메모리 그룹에 배치됩니다.
먼저 선택 사항 (T 값), 즉 생성자가 개인 권한이며 외부로 호출 할 수 없다고 설명하겠습니다. 다른 세 가지 기능은 우리가 전화하는 공개 권한입니다. 그런 다음 선택 사항의 본질은 실제 가치를 내부적으로 저장하는 것이며, 구성 할 때 그 값이 비어 있는지 직접 판단됩니다. 좋아, 그것은 여전히 상당히 추상적이다. 아래 그림과 같이 옵션 (t 값) 생성자의 소스 코드를 직접 업로드하십시오.
그런 다음 (t 값)의 소스 코드는 다음과 같습니다.
public static <t> 옵션 <t> of (t value) {return new Optional <> (value); } 다시 말해, 생성자는 (t 값) 함수에 의해 내부적으로 호출됩니다. 생성자의 소스 코드를 기반으로 두 가지 결론을 도출 할 수 있습니다.
(1) 값의 값이 비어있는 경우 NullPointerException이 여전히보고됩니다.
(2) (t 값) 함수에 의해 구성된 선택적 객체는 값 값이 비어 있지 않을 때 정상적으로 구성 될 수 있습니다.
또한 옵션 클래스는 아마도 다음과 마찬가지로 값 null을 가진 객체를 유지합니다.
공개 최종 클래스 옵션 <t> {// 생략 ...... 개인 정적 최종 선택 사항 <?> 빈 = 새로운 옵션 <> (); 개인 옵션 () {this.value = null; } // 생략 ... public static <t> 옵션 <t> empty () {@suppresswarnings ( "선택 취소") 선택 사항 <t> t = (선택 사례 <t>) 빈; 반환 t; }} 그런 다음 빈 ()의 함수는 빈 객체를 반환하는 것입니다.
글쎄, 너무 많은 준비가 마련되었습니다. OfNullable (t 값)에 기능이 있으며 소스 코드가 추가된다고 말할 수 있습니다.
public static <t> 옵션 <t> ofnullable (t value) {return value == null? empty () : of (value); } 글쎄, 모든 사람은 그것이 의미하는 바를 이해해야합니다. (t 값)과 비교 한 차이는 값 값이 NULL 일 때 (t 값)의 널리 퍼지 네터 렉싱을보고한다는 것입니다. ofnullable (t 값)은 예외를 던지지 않으며, unnullable (t 값)은 빈 객체를 직접 반환합니다.
그것은 우리가 프로젝트에서 기능 대신 무효 기능 만 사용한다는 것을 의미합니까?
아니요, 무언가가 존재하면 자연스럽게 가치가 있습니다. 우리가 달릴 때는 NullPointerException을 숨기고 싶지 않습니다. 대신 즉시보고해야 하며이 경우 기능을 사용해야합니다. 그러나 나는 그런 장면이 거의 없다는 것을 인정해야합니다. 블로거는 Junit 테스트 사례를 작성하는 데만이 기능을 사용했습니다.
(2) ORELSE (T OTH), ORELSEGET (공급 업체 <? extends t> Other) 및 OrelSetHrow (공급 업체 <? extends x> exceptionSupplier)
이 세 가지 기능은 그룹에서 암기되며 생성자가 전달한 값이 NULL 일 때 호출됩니다. Orelse 및 Orelseget의 사용은 다음과 같습니다. 값이 NULL 인 경우 기본값이 제공됩니다.
@testpublic void test () {user user = null; user = 옵션 .ofNullable (user) .orelse (createUser ()); user = 옵션 .ofNullable (user) .OrelSeget (() -> createUser ()); } public user createUser () {user user = new user (); user.setName ( "Zhangsan"); 리턴 사용자;} 이 두 함수의 차이점 : 사용자 값이 NULL이 아닌 경우 Orelse 함수는 여전히 CreateUser () 메소드를 실행하지만 OrelSeget 함수는 CreateUser () 메소드를 실행하지 않으므로 직접 테스트 할 수 있습니다.
Orelsethrow의 경우 값이 Null 일 때 예외는 직접적으로 버려집니다. 사용량은 다음과 같습니다
user user = null; optional.ofnullable (user) .orelsethrow (()-> 새 예외 ( "사용자가 존재하지 않는다");
(3) 맵 (함수 <? super t,? extends u> mapper) 및 flatmap (함수 <? super t, 옵션 <u >> 맵퍼)
이 두 기능은 메모리 세트에 배치 되며이 두 기능은 값을 변환하는 작업을 수행합니다.
소스 코드를 직접 업로드하십시오
공개 최종 클래스 옵션 <t> {// 생략 ...... public <u> 옵션 <u> map (function <? super t,? extends u> mapper) {objects.requirenonnull (mapper); if (! ispresent ()) return empty (); else {return optional.ofnullable (mapper.apply (value)); }} // 생략 ... public <u> 옵션 <u> flatmap (function <? super t, 옵션 <u >> mapper) {objects.requirenonnull (mapper); if (! ispresent ()) return empty (); else {return object.requirenonnull (mapper.apply (value)); }}} 기능 본문 에서이 두 기능 사이에는 차이가 없습니다. 유일한 차이점은 항목 매개 변수입니다. 맵 함수에서 허용되는 항목 매개 변수 유형은 함수 <? 슈퍼 T,? flapmap의 항목 매개 변수 유형이 함수 <? Super T, 옵션 <U >>.
특정 사용 측면에서지도 :
사용자 구조가 다음과 같습니다
공개 클래스 사용자 {개인 문자열 이름; 공개 문자열 getName () {return name; }}현재 이름을 작성하는 글쓰기 방법은 다음과 같습니다.
String City = Optional.ofNullable (user) .map (u-> u.getname ()). get ();
flatmap :
사용자 구조가 다음과 같습니다
공개 클래스 사용자 {개인 문자열 이름; 공개 옵션 <string> getName () {return optional.ofNullable (이름); }}현재 이름을 작성하는 글쓰기 방법은 다음과 같습니다.
String City = Optional.ofNullable (user) .flatmap (u-> u.getName ()). get ();
(4) ISPRESENT () 및 IFPRESENT (소비자 <? Super T> Consumer)
이 두 기능을 모아 외우십시오. ISPRESENT는 값이 비어 있는지 판단하는 것을 의미하며, IFPRESENT는 값이 비어 있지 않을 때 일부 작업을 수행하는 것을 의미합니다. 이 두 기능의 소스 코드는 다음과 같습니다.
공개 최종 클래스 선택 사항 <t> {// 생략 ...... public boolean ispresent () {return value! = null; } // 생략 ... public void ifpresent (소비자 <? super t> consumer) {if (value! = null) 소비자 (value); }}추가 설명이 필요합니다
if (user! = null) {// todo : do do do}}쓴
사용자 user = 옵션 .ofNullable (user); if (옵션.ispresent ()) {// todo : do do something} 이 때문에 코드 구조는 여전히 못 생겼습니다. 블로거는 나중에 올바른 글쓰기 방법을 제공 할 것입니다
ifpresent (소비자 <? super t> consumer)의 경우, 아래에 표시된 것처럼 사용법도 매우 간단합니다.
Optional.ofnullable (user) .ifpresent (u-> {// todo : do do something});(5) 필터 (Predicate <? Super T> Predictate)
더 이상 고민하지 않고 소스 코드를 업로드하십시오
공개 최종 클래스 옵션 <t> {// 생략 ...... Objects.Requirenonnull (PRECTICE); if (! ispresent ())을 반환합니다. 그렇지 않으면 predict.test (value)를 반환합니까? 이것 : empty ();} 필터 메소드는 옵션에 포함 된 값을 필터링하는 술어를 수락합니다. 포함 된 값이 조건을 충족하는 경우 옵션이 여전히 반환됩니다. 그렇지 않으면 선택 사항이 반환됩니다.
사용량은 다음과 같습니다
옵션 <user> user1 = 옵션 .ofnullable (user) .filter (u-> u.getname (). length () <6);
위에서 볼 수 있듯이 사용자 이름의 길이가 6 미만인 경우 반환하십시오. 6보다 큰 경우 빈 객체가 반환됩니다.
실용적 사용
예 1
기능 방법
이전 글
public string getCity (user user)는 예외를 던져 {if (user! = null) {if (user.getAddress ()! = null) {주소 주소 = user.getAddress (); if (address.getCity ()! = null) {return address.getCity (); }}} 새로운 Expetion ( "value error")을 던지십시오. }Java8 쓰기 방법
public string getCity (사용자 사용자)는 예외 {return optional.ofNullable (user) .map (u-> u.getAddress ()) .map (a-> a.getCity ()) .OrelSetHrow (()-> new Exception ( "Fetch Error"));}예 2
예를 들어, 주요 프로그램에서
이전 글
if (user! = null) {dosomething (user);}Java8 쓰기 방법
Optional.ofnullable (user) .ifpresent (u-> {dosomething (u);});예 3
이전 글
public user getUser (user)는 예외 {if (user! = null) {문자열 이름 = user.getName (); if ( "Zhangsan".Equals (name)) {return user; }} else {user = new user (); user.setName ( "Zhangsan"); 리턴 사용자; }}Java8 쓰기 방법
public user getUser (user user) {return optional.ofnullable (user) .filter (u-> "zhangsan".equals (u.getName ())) .OrelSeget (()-> {user user1 = new user (); user1.setName ( "Zhangsan");});});다른 예제는 하나씩 나열되지 않습니다. 그러나 블로거는이 체인 프로그래밍을 사용하는 것이 실제로 코드에서 우아하다고 생각합니다. 그러나 논리는 그다지 명백하지 않으며 가독성이 줄어 듭니다. 우리는 프로젝트의 상황에 따라 사용합니다.
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.