Only null != obj will be judged as null, 10 tricks let you bid farewell to null pointer exception!

I believe that Java programmers are familiar with NPE exception, which is the abbreviation of NullPointerException; recently, the development of business requirements is a bit anxious, and NPE exceptions appear from time to time in the test environment, which is a special headache; as one of the most frequently seen exceptions, once you start Java development , it can be said that it will accompany you throughout your career; whether you are a novice Xiaobai or an old driver, you are both "love" and ruthless towards NPE abnormalities. The main reason for love is that it is easy to deal with. Will step on the pit; in order to improve the quality of the code, NPE exceptions must be eliminated;

Since it is easy to deal with, what is there to worry about? Honestly, the verification is not over, but the experience for programmers during the whole processing process is very bad;

  • make the code verbose

    In many cases, the amount of core business logic code is not large, but once various judgments and verifications are added, the code will become redundant, and the readability and maintainability will decrease accordingly;

  • Pure hard work

    This kind of mechanical empty judgment and verification is essentially physical work, and there is no coding fun at all. Writing this kind of code for a long time will lose the passion for programming;

  • Easy to take the blame

    Many businesses require the cooperation of multiple people, and sometimes there may be a fluke, thinking that other people will handle it when they use it; some pits have been dug invisibly, and the pot will fall from the sky if you are not careful;

Based on these not-so-good experiences above, the difficulty of elimination has increased a lot;

Sometimes when the demand is very urgent, most of the programmers will choose to focus on functions, and some less important things are always thought to be added later, and the important content is skipped first, and the result is that there is nothing after skipping. up;

In order to solve the NPE problem without affecting our development efficiency; JDK and the three-party framework provide us with many excellent tools, so there is no need to waste time and effort to reinvent the wheel;

Here are 10 coups to completely solve the NPE problem:

1Objects tool class

Since it is necessary to solve the null pointer, it is natural to perform a null check on the object in advance; under normal circumstances, it will be used to check the if( null != obj )object; in Java 7, a tool class is specially provided java.util.Objectsto make the null check of the object easier;

features

  • Java 7 comes with no additional dependencies

  • static method, easy to use

  • Only supports object null detection

example

  • Objects.isNull

    Determine whether the object is empty, nullreturn true, otherwise returnfalse

    Object obj = null;
    System.out.println(Objects.isNull(obj)); // true
    
    obj = new Object();
    System.out.println(Objects.isNull(obj)); // false
    
  • Objects.nonNull

    And Objects.isNullthe opposite; judge the object is not empty, nullreturn false, otherwise returntrue

    Object obj = null;
    System.out.println(Objects.nonNull(obj)); // false
    
    obj = new Object();
    System.out.println(Objects.nonNull(obj)); // true
    
  • Objects.requireNonNull

    Verify that it is not empty. Once the object is empty, a NullPointerException will be thrown. You can customize the exception description by changing the method, so that you can quickly locate the problem after the exception:

    Object obj = null;
    Objects.requireNonNull(obj);
    // 自定义错误描述
    Objects.requireNonNull(obj,"obj 对象为空");
    

    Execution output:

    Exception in thread "main" java.lang.NullPointerException: obj 对象为空
     at java.util.Objects.requireNonNull(Objects.java:228)
     at com.ehang.helloworld.controller.NullTest.t5(NullTest.java:97)
     at com.ehang.helloworld.controller.NullTest.main(NullTest.java:23)
    

2 The string is judged to be empty

Strings are the most used data type in the development process, so the judgment and verification of strings are essential. The native method is to judge the length of empty objects:

String str = "一行Java"
if ( null != str && s1.length() > 0 ){
 // 对str字符串进行使用
}

However, in addition to judging the empty string, there are many other scenarios for checking the string, such as judging whether it is an empty string (String str = ), whether there are  ""only spaces (String str =  " "), etc., then these checks , it will be a little troublesome; but it doesn't matter, the ready-made tools are enough;

Spring StringUtil tool class

org.springframework.util.StringUtils It is a string tool class that comes with the String framework, and its functions are relatively simple. In the new version of the teaching tool, the string null detection method of this tool class has been deprecated, so it is not recommended to use it;

  • StringUtils.isEmpty

    Validation of empty objects and empty strings;

    String s1 = null;
    String s2 = "";
    String s3 = " ";
    System.out.println(StringUtils.isEmpty(s1)); // true
    System.out.println(StringUtils.isEmpty(s2)); // true
    System.out.println(StringUtils.isEmpty(s3)); // false
    

Apache lang3 StringUtil tool class

The apache lang3 StringUtil tool class ( org.apache.commons.lang3.StringUtils) is more powerful than the tool class brought by the Spring framework, covering all the encapsulation of String operations;

There are mainly 4 for null check StringUtils.isEmpty, StringUtils.isNotEmpty, StringUtils.isBlank,StringUtils.isNotBlank

  • rely

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
    
  • StringUtils.isEmptyandStringUtils.isNotEmpty

    Determine whether the string object is empty and whether the length of the string is 0; the check results of isEmpty and isNotEmpty are opposite;

    String s1 = null;
    String s2 = "";
    String s3 = " ";
    System.out.println(StringUtils.isEmpty(s1)); // true
    System.out.println(StringUtils.isEmpty(s2)); // true
    System.out.println(StringUtils.isEmpty(s3)); // false
    System.out.println();
    System.out.println(StringUtils.isNotEmpty(s1)); // false
    System.out.println(StringUtils.isNotEmpty(s2)); // false
    System.out.println(StringUtils.isNotEmpty(s3)); // true
    
  • StringUtils.isBlankStringUtils.isNotBlank

    On  the basis of the sum StringUtils.isEmptyand StringUtils.isNotEmpty judgment, after removing the spaces at the beginning and end of the string, it is judged whether the length is greater than 0

    String s1 = null;
    String s2 = "";
    String s3 = " ";
    String s4 = " 1  2    ";
    System.out.println(StringUtils.isBlank(s1)); // true  空对象
    System.out.println(StringUtils.isBlank(s2)); // true  长度等于0
    System.out.println(StringUtils.isBlank(s3)); // true  去掉前后空格之后,长度也等于0
    System.out.println(StringUtils.isBlank(s4)); // false 去掉前后空格(1  2),长度大于0
    System.out.println();
    System.out.println(StringUtils.isNotBlank(s1)); // false
    System.out.println(StringUtils.isNotBlank(s2)); // false
    System.out.println(StringUtils.isNotBlank(s3)); // false
    System.out.println(StringUtils.isNotBlank(s4)); // true
    
  • Other functions

    This article mainly discusses the null check. The StringUtil tool class of lang3 covers almost all the encapsulation of String operations, which greatly reduces the complexity of our String processing. For more functions, please refer to the official documentation

    https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html

3 string comparison

When comparing strings, you also need to pay special attention to NPE exceptions;

For example:

public Boolean isEhang(String name) {
    if (name.equals("ehang")) {
        return true;
    }
    return false;
}

When the name is null, an NPE exception will occur;

The following adjustments can be made:

if ("ehang".equals(name))
...

In this way, even if the name is null, there will be no NPE exception, and it can be judged normally;

4Map, List, Set judge empty

Map, List, and Set are data structures that are often used. Although they all contain isEmpty()methods to determine whether the container contains elements, they cannot determine whether the self-generated object is empty. Once the object is not instantiated, call isEmpty() A null pointer exception will be reported; Spring provides us with a org.springframework.util.CollectionUtilstool class, which isEmptywill first judge whether the object is empty, and then judge whether there is an element through isEmpty(), which can greatly reduce the null pointer caused by the object being empty abnormal;

Map map = null;
System.out.println(map.isEmpty()); // 空指针异常
System.out.println(CollectionUtils.isEmpty(map)); // true
map = new HashMap();
System.out.println(map.isEmpty()); // true
System.out.println(CollectionUtils.isEmpty(map)); // true
map.put("1", "2");
System.out.println(CollectionUtils.isEmpty(map)); // false
System.out.println(map.isEmpty()); // false

List list = null;
System.out.println(list.isEmpty()); // 空指针异常
System.out.println(CollectionUtils.isEmpty(list)); // true
list = new ArrayList();
System.out.println(list.isEmpty()); // true
System.out.println(CollectionUtils.isEmpty(list)); // true
list.add("1");
System.out.println(CollectionUtils.isEmpty(list)); // false
System.out.println(list.isEmpty()); // false

Set set = null;
System.out.println(set.isEmpty()); // 空指针异常
System.out.println(CollectionUtils.isEmpty(set)); // true
set = new TreeSet();
System.out.println(set.isEmpty()); // true
System.out.println(CollectionUtils.isEmpty(set)); // true
set.add("1");
System.out.println(CollectionUtils.isEmpty(set)); // false
System.out.println(set.isEmpty()); // false

In addition to empty judgment, the tool class also contains many useful methods, such as getting the first element: firstElement(), the last element: lastElement(), whether it contains an element: contains(), etc.

hutool的CollectionUtil

Simply judge the empty space, the previous Spring CollectionUtils is enough, and other functions are also sufficient to meet most usage scenarios; hutool的CollectionUtilmore complete functions are provided, and you can also choose if necessary;

rely:

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.7.22</version>
</dependency>

 

5 Assign initial value, try not to return null object

When defining local variables and defining object properties, those that can be assigned initial values ​​should be provided with initial values ​​as much as possible;

Map map = new HashMap();

private Integer age = 0;

When the method has a return value, try not to return null unless necessary;

For example, the execution of a method finally returns a List. When the List has no value, instead of returning a null object, an empty List can be returned.

public List select(){
    // 这里处理其他逻辑
    // 一旦返回的是null是,返回一个空List对象
    return Collections.emptyList();
}

6Optional

Optional is an object container provided by Java 8. The purpose is to effectively solve this annoying null pointer exception. We can regard Optional as an object for the wrapper class;

  • Instantiate the Optional object

    Object o1 = null;
    Optional<Object> op1 = Optional.of(o1);
    Optional<Object> op2 = Optional.ofNullable(o1);
    

    Optional.of()

    When the object is null, the creation process will throw an NPE exception

    Optional.ofNullable()

    When the object is null, the Optional object can also be returned normally

  • Empty isPresent()

    Integer i1 = null;
    Optional<Integer> op1 = Optional.of(i1);
    System.out.println(op1.isPresent()); // false
    
    Integer i2 = 123;
    Optional<Integer> op2 = Optional.ofNullable(i2);
    System.out.println(op2.isPresent()); // true
    op2.ifPresent(i->{
        System.out.println(i);
    });
    

    isPresent() returns true when the object is null and false when it is not empty

    Chain processing of lambda expressions:

    op2.ifPresent(obj->{
        System.out.println(obj);
    });
    
  • value

    // 取出原值,如果原对象为null会报NoSuchElementException异常
    Integer integer = op2.get();
    // 取出原值,如果原值为空,则返回指点的默认值
    Integer integer1 = op1.orElse(456);
    // 取出原值,如果原值为空,返回默认值,不过在返回之前还需要做一些其他的事情
    Integer integer2 = op2.orElseGet(() -> {
        // 在这里做一些其他的操作
        return 456;
    });
    
    // 取出原值,如果原值为空,就抛出指定的异常
    op2.orElseThrow(RuntimeException::new);
    op2.orElseThrow(() -> new RuntimeException("不好,我的值是空的!"));
    
  • map() and flatMap()

    During the encoding process, there are often chain calls like: a.xxx().yyy().zzz().mmm(). Once there is a problem in any link in the process, NPE will be abnormal. Therefore, we You can use map() and flatMap() to avoid this problem;

    Test object:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    static class User {
        private String name;
    
        private Integer age;
    
        private Optional<String> addr;
    }
    

    test:

    // 得到姓名的长度,如果没有姓名就返回0
    Integer nameLen = Optional.of(new User(null, 10, null))
            .map(User::getName)
            .map(String::length)
            .orElse(0);
    System.out.println(nameLen);
    
    // 得到地址的长度,如果没有姓名就返回0
    Integer addr = Optional.of(new User(null, 10, Optional.of("北京")))
            .flatMap(User::getAddr)
            .map(String::length)
            .orElse(0);
    System.out.println(addr);
    

    map will encapsulate the returned object into an Optional object. If the returned object itself is an Optional object, then use flatMap()

7 Affirmations

The translation in Spring  is " assertionorg.springframework.util.Assert "  in Chinese , which is used to determine whether an actual operating value is consistent with the expected item, and an exception is thrown if it is inconsistent. With the help of this class, you can also do a null test;

The Assert class provides the following static methods:

method name describe throw exception on failure
isNull(Object object, String message) object is not null, an exception is thrown IllegalArgumentException
notNull(Object object, String message) object is empty, an exception is thrown IllegalArgumentException
hasLength(String text, String message) text is an empty string, an exception is thrown IllegalArgumentException
hasText(String text, String message) does not contain a blank string, an exception is thrown IllegalArgumentException
doesNotContain(String textToSearch, String substring, String message) textToSearch contains substring, throws an exception IllegalArgumentException
notEmpty(Object[] array, String message) array is empty or the length is 1, an exception is thrown IllegalArgumentException
noNullElements(Object[] array, String message) If the array contains null elements, an exception will be thrown IllegalArgumentException
notEmpty(Collection collection, String message) collection contains no elements, an exception is thrown IllegalArgumentException
notEmpty(Map map, String message) If the map contains null, an exception is thrown IllegalArgumentException
isInstanceOf(Class type, Object obj, String message) If obj is not of type type, an exception is thrown IllegalArgumentException
isAssignable(Class superType, Class subType, String message) subType is not a superType subclass, an exception is thrown IllegalArgumentException
state(boolean expression, String message) expression is not true and an exception is thrown IllegalStateException
isTrue(boolean expression, String message) expression is not true and an exception is thrown IllegalArgumentException
Integer i1 = null;
Assert.notNull(i1,"i1 不为空");

Map map = null;
Assert.notEmpty(map,"map 不为空");

abnormal:

Exception in thread "main" java.lang.IllegalArgumentException: map 不为空
 at org.springframework.util.Assert.notEmpty(Assert.java:555)
 at com.ehang.helloworld.controller.NullTest.t6(NullTest.java:119)
 at com.ehang.helloworld.controller.NullTest.main(NullTest.java:23)

pay attention:

Assert is used to determine whether an actual operating value is consistent with the expected item, so it is the opposite of the verification method of other tool classes; for example, the method isNullexpects the object to be null, and if it is not empty, an error will be reported; notNullIndicates that the expected object is not empty, and when the object is empty, an error will be reported;

8 Local variables use basic data types

In the previous article " Why Ali Prohibits the Use of Basic Data Types in Objects ", from the perspective of performance, it is recommended to use basic data types as much as possible for the definition of local variables. Using basic data types can also effectively avoid null pointer exceptions;

Examples are as follows:

int x;
Integer y;
System.out.println( x + 1 );  // 编译失败
System.out.println( y + 1 );  // 编译失败

int i = 1;
Integer j = null;
System.out.println( i + 1 );  // 正常
System.out.println( j + 1 );  // 空指针异常
int m = i; // 正常
int n = j; // 空指针异常

When the variables x and y are only defined and not assigned, x + 1 and y + 1 cannot be compiled; and the packaging class j can specify objects. When the packaging class participates in the operation, the unboxing operation will be performed nullfirst , that is to call the intValue() method. Since the object is empty, the calling method will naturally report a null pointer; at the same time, when assigning a wrapper class to a basic data type, the unboxing operation will also be performed, and naturally it will be empty The pointer is abnormal;

However, the basic data type must specify a specific value, and there will be no null pointer exception regardless of subsequent operations or assignment operations;

9 Verify parameters in advance

Most of the background data is transmitted through terminal requests, so it is necessary to verify the parameters of the verification at the place closest to the user; for example, the StringBoot project needs to pass the parameters requested by the client at the Controller layer For verification, once the parameters that must be passed do not have a value, you should directly report an error to the client and remind the user, instead of passing these null values ​​that do not meet the requirements to the Service or even save them in the database. Verify and intercept them as soon as possible. Can greatly reduce the probability of problems

The previous introduction hibernate-validatorcan perfectly solve the problem of parameter verification. For details, see: SpringBoot! Are your requests, responses, and exceptions standardized?

10IDEA Reminder

IDEA will remind you of empty objects or objects that may have null values, and you can perceive and prevent them in advance according to the reminders

public static String t1(int i){
    String name1 = null;
    String name2 = null;
    if(i>0){
        name2 = "ehang";
    }
    t2(name1);
    t2(name2);
    return name2;
}

Guess you like

Origin blog.csdn.net/zhangjiaming_zjm/article/details/131173857