The trigonometric operator has long been a favorite of many developers. It simplifies the bloated if-else notation and replaces it with a single line of code, which feels like a nice trick.Little did they know that such a handsome code also hidden a BUG.

The reason

The night before, a feature was released that was supposed to be a bland demand, but the next day Kibana posted tons of NPE logs. Most of these NPE logs point to a line of code I wrote, and I immediately push my glasses and start digging.

The problem code

Kibana’s stack log is located at line 899.

resultMap.put("unAuditPurchaseOrder", switchConf == null ? 0 : switchConf.getUnAuditPurchaseOrder());
Copy the code

1. Check resultMap. It has instantiation on it and cannot be empty.

2. Check switchConf, but null is declared here and no error is reported. What’s that about ????

Continue to troubleshoot

Since you can’t see it with the naked eye, you have to get a test machine and use Arthas to see what’s going on. (Use with caution online as it may cause stutter)

trace com.aaa.bbb.ccc.ddd.eee.CustomerButtonService getPurchaseConfig -n 5 '1==1' --skipJDKMethod false
Copy the code

Sure enough, there’s a clue. IntValue ()! In other words, ifswitchConf.getUnAuditPurchaseOrder()If this is null, then it is clear that an NPE has occurred.

Take a look at the bytecode

And to do that, I’m going to switch to a simple program

public class Test {

    public static void main(String[] args) {

        Integer i = null;
        System.out.println(1! =1 ? 0: i); }}Copy the code

Locate the class file directory and execute

javap -c -l Test
Copy the code

And then I changed the program again

public class Test {

    public static void main(String[] args) {

        Integer i = null;
        System.out.println(1= =1 ? 0: i); }}Copy the code

This run does not report an error. Take a look at its JVM instructions:The result of the ternary operator is the logic of the former, which returns a constant 0.

explain

As you can see from the above experiment, the JVM interprets the ternary operators by checking the data types of the two logical statements against the basic data types. In the experiment, the data type is the basic data type, so if the logic goes to the latter, it is automatically unpacked. This implicit operation is the cause of the BUG.

To solve

Now that we know why, we just need to unify the data types:

public class Test {

    public static void main(String[] args) {

        Integer i = null;
        System.out.println(1! =1 ? new Integer(0) : i); }}Copy the code

Then, as usual, let’s look at his JVM instructions:

gleanings

Later inadvertently found that this example in the “Alibaba development manual” among the recordsIn fact, it is the same thing!

subsequent

Finally, although the problem is solved, but I was tested students recorded a black list, this pot has to carry ~