In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Today, the editor will share with you the relevant knowledge points of the common pits in Java, which are detailed in content and clear in logic. I believe most people still know too much about this knowledge, so share this article for your reference. I hope you can get something after reading this article. Let's learn about it.
1. Preface
For the same code "pit", the first step is called "gained experience", the second step is called "deepen impression", the third time is called "not thoughtful", and if you step more than three times, it is called "hopeless". In this paper, the author summarizes some code pits, describes the problem phenomena, analyzes the problems, and gives the methods to avoid the code pits. I hope that when you encounter this kind of code pit in your daily coding, you can avoid it in advance.
1. Object comparison method
The Objects.equals method provided by JDK1.7 conveniently realizes the comparison of objects and effectively avoids the tedious null pointer check.
1.1. Problem phenomenon
Before JDK1.7, when judging whether a short, long, or long integer wrapper data type is equal to a constant, we used to write:
Short shortValue = (short) 12345 / system. Out.println (shortValue = = 12345); / / trueSystem.out.println (12345 = = shortValue); / / trueInteger intValue = 12345 / system. Out.println (intValue = = 12345); / / trueSystem.out.println (12345 = = intValue); / / trueLong longValue = 12345L / system. Out.println (longValue = 12345); / / trueSystem.out.println (12345 = = longValue); / / true
After JDK1.7, the Objects.equals method is provided and functional programming is recommended. The change code is as follows:
Short shortValue = (short) 12345 / system. Out.println (Objects.equals (shortValue, 12345)); / / falseSystem.out.println (Objects.equals (12345, shortValue)); / / falseInteger intValue = 12345 / system. Out.println (Objects.equals (intValue, 12345)); / / trueSystem.out.println (Objects.equals (12345, intValue)); / / trueLong longValue = 12345L / system. Out.println (Objects.equals (longValue, 12345)); / / falseSystem.out.println (Objects.equals (12345, longValue)) / / false
Why does directly replacing = = with the Objects.equals method result in a different output?
1.2. Analysis of problems
By decompiling the first piece of code, we get the bytecode instruction for the statement "System.out.println (shortValue = = 12345);" as follows:
7 getstatic java.lang.System.out: java.io.PrintStream [22] 10 aload_1 [shortValue] 11 invokevirtual java.lang.Short.shortValue (): short [28] 14 sipush 1234517 if_icmpne 2420 iconst_121 goto 2524 iconst_025 invokevirtual java.io.PrintStream.println (boolean): void [32]
It turns out that the compiler will judge the basic data type corresponding to the wrapper data type and compare it with the instructions of this basic data type (such as sipush and if_icmpne in the bytecode instruction above), which is equivalent to the forced conversion of the constant data type by the compiler automatically.
Why doesn't the compiler automatically cast data types on constants after using the Objects.equals method? By decompiling the second piece of code, we get the bytecode instruction for the statement "System.out.println (Objects.equals (shortValue, 12345));" as follows:
7 getstatic java.lang.System.out: java.io.PrintStream [22] 10 aload_1 [shortValue] 11 sipush 1234514 invokestatic java.lang.Integer.valueOf (int): java.lang.Integer [28] 17 invokestatic java.util.Objects.equals (java.lang.Object, java.lang.Object): boolean [33] 20 invokevirtual java.io.PrintStream.println (boolean): void [39]
It turns out that the compiler literally believes that the default basic data type of constant 12345 is int, so it is automatically converted to the wrapper data type Integer.
In the Java language, the default data type for integers is int and the default data type for decimals is double.
Let's analyze the code implementation of the Objects.equals method:
Public static boolean equals (Object a, Object b) {return (a = = b) | (a! = null & & a.equals (b));}
Where the statement "a.equals (b)" will use the Short.equals method.
Public boolean equals (Object obj) {if (obj instanceof Short) {return value = = ((Short) obj) .shortValue ();} return false;}
Through the code implementation analysis: the corresponding statement "System.out.println (Objects.equals (shortValue, 12345));", because the two parameter object types of Objects.equals are inconsistent, one is the wrapper data type Short, the other is the wrapper data type Integer, so the final comparison result must be false. Similarly, the statement "System.out.println (Objects.equals (intValue, 12345));", because the two parameter objects of Objects.equals are of the same type, both wrap the data type Integer with the same value, so the final comparison result must be true.
1.3. Pit avoidance method
1. Keep good coding habits and avoid automatic conversion of data types.
In order to avoid automatic conversion of data types, a more scientific way to write is to directly declare the constant as the corresponding basic data type.
The first piece of code can be written as follows:
Short shortValue = (short) 12345th System.out.println (shortValue = = (short) 12345); / / trueSystem.out.println ((short) 12345 = = shortValue); / / trueInteger intValue = 12345ash System.out.println (intValue = = 12345); / / trueSystem.out.println (12345 = = intValue); / / trueLong longValue = 12345L Shield System.out.println (longValue = = 12345L); / / trueSystem.out.println (12345L = longValue); / / true
The second piece of code can be written as follows:
Short shortValue = (short) 12345 / system. Out.println (Objects.equals (shortValue, (short) 12345)); / / trueSystem.out.println (Objects.equals (short) 12345, shortValue)); / / trueInteger intValue = 12345 / boot / system. Out.println (Objects.equals (intValue, 12345)); / / trueSystem.out.println (Objects.equals (12345, intValue)); / / trueLong longValue = 12345L / System.out.println (Objects.equals (longValue, 12345L)) / / trueSystem.out.println (Objects.equals (12345L, longValue)); / / true
2. Find the data type mismatch early with the help of development tools or plug-ins.
In the questions window of Eclipse, we will see the following prompt:
Unlikely argument type for equals (): int seems to be unrelated to ShortUnlikely argument type for equals (): Short seems to be unrelated to intUnlikely argument type for equals (): int seems to be unrelated to LongUnlikely argument type for equals (): Long seems to be unrelated to int
Through the FindBugs plug-in scan, we will see a warning like this:
Call to Short.equals (Integer) in xxx.Xxx.main (String []) [Scariest (1), High confidence] Call to Integer.equals (Short) in xxx.Xxx.main (String []) [Scariest (1), High confidence] Call to Long.equals (Integer) in xxx.Xxx.main (String []) [Scariest (1), High confidence] Call to Integer.equals (Long) in xxx.Xxx.main (String []) [Scariest (1), High confidence]
3. Conduct routine unit testing and try to find the problem at the stage of research and development.
"Don't give up doing good even if it's not important." Don't do unit testing just because the changes are small. Bug often appears in your overconfident code. Problems like this can be found by conducting a unit test.
two。 Unpacking of ternary expression
Ternary expression is a fixed syntax format in Java coding: conditional expression? expression 1: expression 2.
The logic of the ternary expression is: "if the conditional expression is valid, execute expression 1, otherwise execute expression 2."
2.1. Problem phenomenon boolean condition = false;Double value1 = 1.0D / double value2 = 2.0D / s double value3 = null;Double result = condition? Value1 * value2: value3; / / throws a null pointer exception
When the conditional expression condition is equal to false, directly assign the Double object value3 to the Double object result, according to reason, there is no problem, why throw a null pointer exception (NullPointerException)?
2.2. Analysis of problems
By decompiling the code, we get the bytecode instruction for the statement "Double result = condition? value1 * value2: value3;" as follows:
17 iload_1 [condition] 18 ifeq 3321 aload_2 [value1] 22 invokevirtual java.lang.Double.doubleValue (): double [24] 25 aload_3 [value2] 26 invokevirtual java.lang.Double.doubleValue (): double [24] 29 dmul30 goto 3833 aload 4 [value3] 35 invokevirtual java.lang.Double.doubleValue (): double [24] 38 invokestatic java.lang.Double.valueOf (double): java.lang.Double [16] 41 astore 5 [result] 43 getstatic java.lang.System.out : java.io.PrintStream [28] 46 aload 5 [result]
On line 33, load the Double object value3 into the Operand stack; on line 35, call the doubleValue method of the Double object value3. At this point, because value3 is an empty object null, calling the doubleValue method must throw a null pointer exception. But why convert an empty object value3 to the underlying data type double?
Consult the relevant data to get the type conversion rules of the ternary expression:
If two expressions are of the same type, the return value type is that type
two。 If the two expression types are different, but the type is not convertible, the return type is Object.
3. If the two expression types are different, but the type can be converted, first convert the wrapper data type to the basic data type, and then follow the conversion rules of the basic data type (byte
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.