NullPointerException을 피하기 위한 6가지 요령

Null 참조는 역사적으로 나쁜 생각이었습니다. 참조를 발명한 Tony Hoarenull조차도 이를 The Billion Dollar Mistake라고 부릅니다.

"I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object-oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years." ~ Charles Antony Richard Hoare



1. 개요

NullPointerException can sometimes be frustrating. It can break your application. It could be difficult to find an actual issue from the production server logs. In this article, I will explain what is java.lang.NullPointerException ? Also, we will see various tips and tricks that will help you in writing better code. If you already have some idea about NullPointerException, skip to the How to avoid NullPointerException? 섹션.

2. NullPointerException이란 무엇입니까?

The NullPointerException is a runtime exception when a program tries to access an object with a null reference. Or, does any operation on a null object. Here is a simple code snippet that throws java.lang.NullPointerException .



여기str는 null이며 모든 작업에서 NullPointerException이 발생합니다. 이 코드를 실행하려고 하면 출력:



이것은 사소한 예입니다. 문자열str이 인수로 제공되거나 데이터베이스 호출의 결과 집합에 제공된 경우 응용 프로그램이 중단된다고 상상해 보십시오. 다음 섹션에서는 NullPointerException을 방지하기 위한 몇 가지 모범 사례를 살펴보겠습니다.

3. NullPointerException을 피하는 방법?

One of the famous ways to avoid java.lang.NullPointerException is to add null checks wherever plausible. However, this approach will make your code bloated with null != something statements. Here are some best practices that you can follow to make your code NullPointerException proof.

3.1. 선택적 클래스 사용



선택적 클래스 기능은 Java 8에서 도입되었습니다. 다음은 선택적 클래스 기능을 활용하여 NullPointerExceptions를 줄이는 방법을 설명하는 예입니다.

import java.util.Optional;

public class Example {
    public static void main(String args[]) {
        String str = null;
        Optional<String> strOpt = Optional.ofNullable(str);
        System.out.print(strOpt.orElse("").length()); // prints 0
    }
}


여기서 strOpt.orElse("")str가 null일 때 빈 문자열을 제공하며 그렇지 않으면 원래 문자열을 반환합니다. 다음은 다양한 시나리오에서 Optional 클래스와 함께 사용할 수 있는 몇 가지 유용한 메서드입니다.
  • public boolean isPresent() - 값이 있으면 true를 반환하고 그렇지 않으면 false를 반환합니다.
  • public T get() - 이 Optional에 값이 있으면 값을 반환하고, 그렇지 않으면 NoSuchElementException을 던집니다.
  • public T orElseGet(Supplier<? extends T> other) - 값이 있으면 값을 반환하고 그렇지 않으면 other를 호출하고 해당 호출의 결과를 반환합니다.

  • Optional 클래스에 대한 자세한 내용은 Optional (Java Platform SE 8) 을 참조하십시오.

    3.2. StringUtils 사용



    StringUtils는 입력 문자열을 조용히 처리합니다null. null 문자열이 전달되면 NullPointerException이 발생하지 않음을 의미합니다. null 문자열을 공백으로 간주합니다. 프로젝트에서 이것을 사용하려면 Apache Commons Lang 에서 StringUtils를 가져와야 할 수도 있습니다. 다음 코드는 StringUtils의 null 안전 기능을 보여줍니다.

    import org.apache.commons.lang3.StringUtils;
    
    public class Example {
        public static void main(String args[]) {
            String str = null;
            System.out.print(StringUtils.length(str)); // prints 0
        }
    }
    


    몇 가지 유용한 StringUtils 메서드는 다음과 같습니다.
  • public static boolean isNotBlank(CharSequence cs) - CharSequence가 비어 있지 않은지, null이 아니며 공백만 없는지 확인합니다.
  • public static boolean equals(CharSequence cs1, CharSequence cs2) - 두 개의 CharSequence를 비교하여 동일한 문자 시퀀스를 나타내는 경우 true를 반환합니다. 두 인수가 모두 null이면 true를 반환합니다.

  • StringUtilshere에 대해 자세히 알아보세요.

    3.3. 기본 데이터 유형 사용



    원시 데이터 유형은 결코 null이 될 수 없기 때문입니다. 가능한 한 다음을 사용해 보십시오.
  • int 대신 Integer .
  • boolean 대신 Boolean .
  • float 대신 Float .
  • double 대신 Double .
  • long 대신 Long .
  • short 대신 Short .
  • char 대신 Character

  • 3.4. 리터럴에서 equals 호출



    두 개의 문자열 또는 열거형 요소를 비교할 때는 항상 왼쪽에 null이 아닌 값을 사용하는 것이 좋습니다. 예시:

    public class Example {
        public static void main(String args[]) {
            String str = null;
            if ("abc".equals(str)) {
                System.out.println(true);
            }
            if (str.equals("abc")) // NullPointerException here
            {
                System.out.println(true);
            }
        }
    }
    
    


    3.5. 삼항 연산자 사용



    삼항 연산자를 사용하면 코드에서 NullPointerException이 발생하는 것을 방지할 수 있습니다. 방법은 다음과 같습니다.

    public class Example {
        public static void main(String args[]) {
            String str = null;
            System.out.println(null == str ? 0 : str.length());
        }
    }
    


    위의 코드는 str이 null이 아니어서 NullPointerException을 방지하는 경우에만 length() 메서드를 호출합니다.

    3.6. IllegalArgumentException 발생



    인수가 null이거나 예상하지 못한 경우 IllegalArgumentException을 발생시키는 것이 항상 모범 사례입니다. 이렇게 하면 무엇이 잘못되었는지 파악하는 데 몇 시간을 절약할 수 있습니다. 다음은 전달된 인수가 null일 때 IllegalArgumentException을 발생시키는 예제 코드입니다.

    public class Example {
        public static void main(String args[]) {
            String str = null;
            printStringLength(str);
        }
        static void printStringLength(String str) {
            if (null == str) {
                throw new IllegalArgumentException("String str was null");
            } else {
                System.out.println(str.length());
            }
        }
    }
    


    4. 결론



    NullPointerException을 피하는 가장 좋아하는 방법 중 하나는 이 문null != obj.getSomething()을 추가하는 것입니다. 그러나 우리는 성숙한 개발자이므로 이러한 null 검사 문으로 코드를 부풀리게 하고 싶지 않습니다. 다음과 같은 코드를 상상해 보십시오.

    if (null != obj 
            && null != obj.getSomething() 
            && null != obj.getSomething().fromHere()
            && null != obj.obj.getSomething().fromHere().property()) {
        // do something with obj.getSomething().fromHere().property()
    }
    


    미친 것 같죠? NullPointerException을 중지하기 위해 내 응용 프로그램 중 하나에서 이것을 작성했습니다. 그러나 이제 우리는 더 나은 방법으로 그들을 피하는 방법을 알고 있습니다.

    읽어 주셔서 감사합니다! NullPointerException을 처리하기 위해 가장 미친 일이 무엇인지 의견에 알려주십시오.

    좋은 웹페이지 즐겨찾기