Java에서 빈 포인터 이상을 방지하는 방법

아무도 빈 바늘 이상을 좋아하지 않을 거야!그것들을 피할 수 있는 방법이 있습니까?혹시
본고는 다음과 같은 몇 가지 기술을 토론할 것이다
1.Optional 유형(Java 8에 새로 도입된)
2. Objects 클래스(Java 7 중원에 있음)
Java 8의 Optional 클래스
그것은 무엇입니까?
1.Java 8에 새로 도입된 유형
2. 이것은 특정한 유형의 대상의 포장기나 존재하지 않는 대상(null)의 장면에 사용된다
간단하게 말하자면, 그것은 빈 값을 처리하는 더 좋은 대체품이다. (경고: 언뜻 보기에는 그렇게 뚜렷하지 않을 수도 있다)
기본용법
그것은 하나의 유형 (한 종류) 이다. 그러면 어떻게 해야만 이 유형의 실례를 만들 수 있습니까?
그것의 세 가지 정적 방법을 사용하면 된다.

public static Optional<String> stringOptional(String input) {
    return Optional.of(input);
}
간단명료합니다. 이 값을 포함하는 Optional 패키지를 만듭니다.기억해라. 만약 이 값이null이라면 NPE를 던질 것이다!

public static Optional<String> stringNullableOptional(String input) {
if (!new Random().nextBoolean()) {
input = null;
}
return Optional.ofNullable(input);
}
나는 개인적으로 좀 더 좋아야 한다고 생각한다.이렇게 하면 NPE의 위험이 없다. null로 입력하면 빈 Optional로 되돌아온다.

public static Optional<String> emptyOptional() {
return Optional.empty();
}
만약 당신이 정말로 빈 값을 되돌려 주기를 원한다면, 빈 값은 null을 의미하지 않습니다.
알겠습니다. 그럼 어떻게 Optional을 소비/사용합니까?

public static void consumingOptional() {
Optional<String> wrapped = Optional.of("aString");
if (wrapped.isPresent()) {
System.out.println("Got string - " + wrapped.get());
}
else {
System.out.println("Gotcha !");
}
}
간단한 방법은 Optional 패키지가 정말 가치가 있는지 확인하는 것이다. (isPresent 방법을 사용하면) 이것은 if(myObj!=null)를 사용하는 것보다 무엇이 좋은지 의심할 것이다.걱정 마, 그건 내가 분명히 설명할게.

public static void consumingNullableOptional() {
String input = null;
if (new Random().nextBoolean()) {
input = "iCanBeNull";
}
Optional<String> wrapped = Optional.ofNullable(input);
System.out.println(wrapped.orElse("default"));
}
만약에 봉인된null값이 확실하다면 기본값을 되돌려 줄 수 있는 orElse 방법을 사용할 수 있습니다.실제 값을 추출할 때 ifPresent 방법을 사용하는 것을 피할 수 있습니다.

public static void consumingEmptyOptional() {
String input = null;
if (new Random().nextBoolean()) {
input = "iCanBeNull";
}
Optional<String> wrapped = Optional.ofNullable(input);
System.out.println(wrapped.orElseGet(
() -> {
return "defaultBySupplier";
}
 
));
}
그건 좀 모르겠어요.왜 같은 목적의 다른 두 가지 방법이 있습니까?orElse와 orElseGet은 분명히 다시 불러올 수 있습니다(같은 이름이지만 다른 매개 변수).
어쨌든, 이 두 가지 방법의 뚜렷한 차이는 바로 그들의 매개 변수에 있다. - 당신은 Supplier의 실례가 아닌 lambda 표현식을 사용하여 이것을 완성할 수 있다.
왜 Optional을 사용하는 것이 흔한 null 검사보다 낫습니까?
1. Optional을 사용하는 가장 큰 장점은 당신의 의도를 더욱 명확하게 표현할 수 있다는 것이다. null값을 되돌리면 소비자들이 의심하게 할 수 있기 때문에 (실제로 NPE가 나타날 때) 일부러 되돌린 것이 아닌지 의심스러워하기 때문에javadoc를 확인해서 더 포지셔닝해야 한다.Optional을 사용하면 상당히 명확합니다.
2. Optional이 있으면 NPE를 철저히 피할 수 있다. 위에서 언급한 바와 같이 Optional을 사용한다.ofNullable, orElse 및 orElseGet은 NPE를 멀리할 수 있습니다.
또 다른 구원의 별!
이 코드 세션 보세요.

package com.abhirockzz.wordpress.npesaviors;
 
import java.util.Map;
import java.util.Objects;
 
public class UsingObjects {
 
String getVal(Map<String, String> aMap, String key) {
return aMap.containsKey(key) ? aMap.get(key) : null;
}
 
public static void main(String[] args) {
UsingObjects obj = new UsingObjects();
obj.getVal(null, "dummy");
}
}
어느 것이 비어 있을 수 있습니까?
1. Map 객체
2. 검색에 사용되는 키
3. 방법 호출의 이 실례
만약 NPE를 던진다면, 우리는 도대체 어느 것이null인지 어떻게 확정할 수 있습니까?

package com.abhirockzz.wordpress.npesaviors;
 
import java.util.Map;
import java.util.Objects;
 
public class UsingObjects {
String getValSafe(Map<String, String> aMap, String key) {
Map<String, String> safeMap = Objects.requireNonNull(aMap,
"Map is null");
String safeKey = Objects.requireNonNull(key, "Key is null");
 
return safeMap.containsKey(safeKey) ? safeMap.get(safeKey) : null;
}
 
public static void main(String[] args) {
UsingObjects obj = new UsingObjects();
obj.getValSafe(null, "dummy");
}
}
requireNonNull 방법
1. 대상이 null이 아니라면 그 자체로 돌아가기
2. 값이 null이면 반환된 NPE에 지정된 메시지가 표시됩니다.
왜 if(my Obj!=null)보다 좋아요?
당신이 본 창고 추적 정보는 Objects를 똑똑히 볼 수 있습니다.requireNonNull 메서드를 호출합니다.이것은 다시 당신의 오류 로그에 맞추면 문제를 더 빨리 포지셔닝할 수 있습니다...적어도 내가 보기엔 더 빨라.
예를 들어 간단한 검사기를 실현하여 빈 값이 없도록 할 수도 있다.

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
 
public class RandomGist {
 
    public static <T> T requireNonEmpty(T object, Predicate<T> predicate, String msgToCaller){
        Objects.requireNonNull(object);
        Objects.requireNonNull(predicate);
        if (predicate.test(object)){
            throw new IllegalArgumentException(msgToCaller);
        }
        return object;
    }
 
    public static void main(String[] args) {
       
    //Usage 1: an empty string (intentional)
 
    String s = "";
    System.out.println(requireNonEmpty(Objects.requireNonNull(s), (s1) -> s1.isEmpty() , "My String is Empty!"));
 
    //Usage 2: an empty List (intentional)
    List list =  Collections.emptyList();
    System.out.println(requireNonEmpty(Objects.requireNonNull(list), (l) -> l.isEmpty(), "List is Empty!").size());
 
    //Usage 3: an empty User (intentional)
    User user = new User("");
    System.out.println(requireNonEmpty(Objects.requireNonNull(user), (u) -> u.getName().isEmpty(), "User is Empty!"));
}
 
    private static class User {
        private String name;
 
        public User(String name){
            this.name = name;
        }
 
        public String getName(){
            return name;
        }
    }
}
NPE가 잘못된 곳에서 고통이 되지 않도록 하세요.우리는 NPE를 더욱 잘 처리하고 심지어는 철저히 근절할 수 있는 많은 도구가 있다.

좋은 웹페이지 즐겨찾기