scenario

There was an online problem and an NPE appeared. The code at that time was like the following:

1. Map<String, service object > Map = xxxservice.findxxx (XXX); 2. Long result = map.get(xxx) ! = null ? map.get(xxx).getId() : 0L;Copy the code

Get (XXX) {get(XXX) {get(XXX)}}

The process of screening problem, search in such a blog: blog.csdn.net/prestonzzh/…

When using a ternary operator, the CPU computes both sides of the ternary operator to make it faster.

Java ternary operators also generate bytecode to run, not directly with the CPU, so let’s look at what bytecode looks like:

public static void main(String[] args) {
    boolean condition = false;
    Long data = 2L;
    Long res = condition ? data : 0L;
    System.out.println(res);
 }
Copy the code

As you can see, ternary operators are no longer ternary operators when compiled into bytecode, but branch via IFEQ, GOTO, and the like if else.

This shows that the NPE error caused by CPU optimization on both sides is untenable. The program must have judged the condition first and then branch according to the condition.

To be more careful here, we can see the words long. longValue and long. valueOf appear in the bytecode.

This refers to the Java concept of unboxing. When the base type and the wrapper type are together, the wrapper type is automatically converted to the base type. That is, when data and 0L are together,

Data in bytecode is automatically changed to data.longvalue (), which is unboxed, so this is dangerous. If data is null, it will cause an error. Let’s verify:

The wrapper type is null. This is not a problem in the syntax phase, but in the runtime phase, an NPE error occurs.

At this point we can change 0L to wrapper type, and then Java won’t automatically change it to base type, because both are wrapper types and we won’t unpack them.

Output NULL smoothly,

You can see that the bytecode is now without long. longValue or long. valueOf, indicating that it has not been unpacked.

Problem symptom Solution

I suspect that the value of map.get(XXX) is not null, but the value of getId() is null, so the unpacking occurs, resulting in NPE.

1. Map<String, service object > Map = xxxservice.findxxx (XXX); 2. Long result = map.get(xxx) ! = null ? map.get(xxx).getId() : 0L;Copy the code

Finally, according to the check of xxxservice.findxxx (XXX) code, if the corresponding information of XXX is not found, a new business object is returned, but the value of the new object is null, so the unpacking causes NPE.

This problem is actually caused by unpacking, far from the CPU level ~ pay more attention to details in the future development process, can not easily suspect CPU, ha ha ~