Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the common pits in Java?

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report