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 ~