In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-26 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 about the analysis of Objects.equals trampling examples in Java. The content is detailed and the logic is clear. I believe most people still know too much about this, so share this article for your reference. I hope you can get something after reading this article. Let's take a look at it.
1. Crime scene
Suppose there is a need to determine who is currently logged in and, if it is our designated system administrator, to send an email. The system administrator does not have a special field identity, and his user id=888 is the same in development, test, and production environments.
This requirement is really too easy to achieve:
UserInfo userInfo = CurrentUser.getUserInfo (); if (Objects.isNull (userInfo)) {log.info ("sign in first"); return;} if (Objects.equals (userInfo.getId (), 888)) {sendEmail (userInfo):}
Get the user information from the context of the currently logged-in user and judge that if the user information is empty, it will be returned directly.
If the user information obtained is not empty, it is then determined whether the user id is equal to 888.
If it is equal to 888, send a message.
If it is not equal to 888, then do nothing.
When we logged in with id=888 's system administrator account, did the relevant operations, and prepared to receive email with great anticipation, we found that we were lonely.
Later, it turns out that the UserInfo class is defined like this:
@ Datapublic class UserInfo {private Long id; private String name; private Integer age; private String address;}
At this point, some friends may say: I don't see any problem.
But what I'm trying to say is that there is something wrong with this code.
What's the problem?
Answer: the member variable id=888 of the UserInfo class is of type Long, while the 888 to the right of the Objects.equals method is of type int, which is inconsistent, resulting in the returned result being false.
What kind of reason is that?
A: ladies and gentlemen, don't worry. We'll talk about it later.
two。 A method of judging equality
Let's review the previous methods of determining whether two values are equal.
2.1 use the = sign
The quickest way to determine whether two values are equal is to use the = sign.
Int a = 1 trueSystem.out.println (a = = d 1); / / result: trueSystem.out.println (a = = D1); / / result: trueSystem.out.println (d 2 = = a); / / result: trueSystem.out.println (d 1 = = d 2); / / result: trueSystem.out.println (d 1 = = d 2); / / result: trueSystem.out.println (d 1 = = d 2); / / result: trueSystem.out.println (d 1 = = d 2); / / result: false
I do not know if you have found that the basic types of java, including: int, long, short, byte, char, boolean, float, double these 8, you can use the number to determine whether the value is equal. If a wrapper class of a basic type appears, such as Integer, use a primitive type and a wrapper class, the usage number can also be correctly judged, and return true.
When comparing Integer and int, the box will be unpacked automatically, which is to compare whether the values are equal.
But if you have two wrapper classes, such as D1 and D2, the result of using the = = sign may be false.
When two Integer are compared, they are compared to see if the references (that is, memory addresses) they point to are equal.
There is another interesting phenomenon:
Integer d3 = 1 x Integer D4 = 1 x Integer D5 = 128 x Integer D6 = 128 X system. Out.println (d 3 = = d 4); / / result: trueSystem.out.println (d 5 = = d 6); / / result: false
All the parameters are assigned to the Integer type, which are directly assigned and compared. The results of d3 and d4 judgment are equal, but the results of d5 and d6 judgment are not equal.
Guys, did you lose your chin?
Answer: because Integer has a constant pool,-128-127 direct Integer data is cached directly into the constant pool. So 1 is in the constant pool and 128 is not.
However, new's Integer object does not apply to constant pooling. This can be seen from the comparison of the previous D1 and D2 examples.
Next, take a look at the string judgment:
String e = "abc"; String f = "abc"; String g = new String ("abc"); String h = new String ("abc"); System.out.println (e = = f); / / result: trueSystem.out.println (e = = g); / / result: falseSystem.out.println (g = = h); / / result: false
Ordinary string variables, judged by the = = sign, can also return correct results.
But if an ordinary string variable is judged by a number with the string object coming out of new, it returns false. This is different from the result of using a basic type and a wrapper class as mentioned earlier, and the string does not have the function of automatic unpacking, which requires special attention.
In addition, the string objects from two new also return false when judged by the = = sign.
2.2 use the equals method
Using the = = sign above, you can quickly determine whether the eight basic data types are equal, and in addition, you can determine whether the references of two objects are equal.
But now there is a problem, it cannot determine whether the specific data values of two objects are equal in memory, such as:
String g = new String ("abc"); String h = new String ("abc"); System.out.println (g = = h); / / result: false
The string objects g and h are two different objects that return false when they use the = = sign to determine whether references are equal.
So, how can we judge equality if the objects are different but the data values are the same?
Answer: use the equals method.
The equals method is actually a method in the Object class:
Public boolean equals (Object obj) {return (this = = obj);}
This method is very simple and only determines whether the references of two objects are equal.
Obviously, if the string type directly uses the equals method of the parent class (that is, the Object class) to determine that the object is different, but the value is the same, it is problematic.
So, the string (that is, the String class) restores the equals method:
Public boolean equals (Object anObject) {if (this = = anObject) {return true;} if (anObject instanceof String) {String anotherString = (String) anObject; int n = value.length; if (n = = anotherString.value.length) {char v1 [] = value; char v2 [] = anotherString.value; int I = 0 While (n return true; -! = 0) {if (v1 [I]! = v2 [I]) return false; iTunes;} return true;}} return false;}
It still determines whether two object references are equal, and returns true if they are equal. Next, the character by character of the two strings is compared, and true is returned only if all characters are equal.
Nice, which solves the problem of g and h judgment:
String e = "abc"; String f = "abc"; System.out.println (e.equals (f)); / / result: true
Thus, we use the overridden equals method of the String class to determine that two string objects are different, but return true when the values are the same.
3. Null pointer exception
As we already know, to determine whether two objects are equal, you can use the = = sign, or the equals method.
But if you use them more deeply, you will find a problem, that is, if the values of the two methods are equal, you may report a null pointer exception.
Let's first take a look at the judgment of the = sign:
Int a = 1 Integer Integer b = new Integer (1); Integer c = null;System.out.println (a = = b); / / result: trueSystem.out.println (a = = c); / / result: NullPointerException
When int and Integer use the = = sign to determine whether they are equal, Integer will automatically unpack the box into int.
However, because c is in the process of automatically unpacking, it needs to be assigned a default value of 0 for int. If you assign a value of 0 to a null object, you will inevitably report a null pointer exception.
Next, take a look at the equals method:
String e = null;String f = "abc"; System.out.println (e.equals (f)); / / result: NullPointerException
Because the string object e is empty, a null pointer exception is reported when its equals method is called directly.
So, how to solve the problem of null pointer?
Answer: empty in the code.
String e = null;String f = "abc"; System.out.println (equals (e, f))
We extract a new equals method:
Private static boolean equals (String e, String f) {if (e = = null) {return f = = null;} return e.equals (f);}
This method can solve the problem of null pointer, but is there any way to encapsulate it, make it more general, and also apply to Integer or other types of object comparison?
A: if there is a way, move on.
4. The role of Objects.equals
The Objects class, located under the java.util package, is an auxiliary method that provides a lot of object manipulation.
Let's focus on its equals method:
Public static boolean equals (Object a, Object b) {return (a = = b) | (a! = null & & a.equals (b));}
The judgment logic of the equals method is as follows:
This method first determines whether the references of objects an and b are equal, and if so, directly returns true.
If the reference is not equal, determine whether an is empty or not, and return false if an is empty.
If an is not empty, the object's equals method is called to further determine whether the value is equal.
How is this method used?
Int a = 1 politics int b = 1 Integer c = null;System.out.println (Objects.equals (a, c)); / / result: falseSystem.out.println (Objects.equals (c, a)); / / result: falseSystem.out.println (Objects.equals (a, b)); / / result: true
As you can see from the columns above, using the Objects.equals method to compare whether two objects are equal does avoid the null pointer problem.
But there is a doubt about this: the previous way to compare references with a null pointer is that when b is empty, the program directly throws a null pointer exception.
The Objects.equals method also uses aequalb to compare whether the reference is equal, so why doesn't it throw an exception?
Answer: because the equals method of the Objects class uses the Object type to receive parameters, and its default value is null, which does not need to be converted or assigned a default value of 0 like the int type object.
From the above theory, we can see that if we change the code like this, we won't throw an exception:
Int a = 1 th Integer c = null;System.out.println (equals (a, c)); / / result: false
A new method is defined:
Private static boolean equals (Object a, Object b) {return a = = b;}
After execution, it was found that there was really no short pointer.
So the Objects.equals method is really a good way to compare whether two objects are equal.
But it has a hole. If you don't believe it, read on.
5. Objects.equals 's pit
When you guys see this, you may be a little anxious. What kind of pit is it?
Don't talk too much nonsense, go straight to the example:
Integer a = 1terlong b = 1LterSystem.out.println (Objects.equals (a, b)); / / result: false
What? The returned result is false?
And if you directly use the = sign to judge:
Integer a = 1x long b = 1L X System.out.println (a = = b); / / result: true
True is returned again.
An and b are obviously 1, so why use Objects.equals method to judge that they are not equal?
This starts with Integer's equals method.
The code for its equals method is as follows:
Public boolean equals (Object obj) {if (obj instanceof Integer) {return value = = ((Integer) obj) .intValue ();} return false;}
First determine whether the parameter obj is of type Integer, and if not, return false directly. If it is the Integer type, further determine whether the int values are equal.
In the above example, b is of type long, so the equals method of Integer returns false directly.
That is, if the equals method of Integer is called, the input parameter must also be of type Integer, otherwise the method will directly return false.
This is where the pit is!
In fact, if you change the code like this:
Integer a = 1terlong b = 1LterSystem.out.println (Objects.equals (b, a)); / / result: false
The result of execution is also false.
Because the equals method code of Long is similar to that of previous Integer:
Public boolean equals (Object obj) {if (obj instanceof Long) {return value = = ((Long) obj) .longValue ();} return false;}
It is also used to determine the input parameter. If it is not of type Long, the method returns false directly.
In addition, Byte, Short, Double, Float, Boolean and Character also have similar equals method judgment logic.
Thus, when we use the Objects.equals method to determine whether two values are equal, we must ensure that the types of the two input parameters are the same. Otherwise, even if the two values are the same, the result will still return false, which is a big pit.
So, how to solve the above problems?
The type of parameter b can be cast to int.
Integer a = 1terlong b = 1LterSystem.out.println (Objects.equals (a, (int) b)); / / result: true
Or cast the type of parameter a to long.
Integer a = 1 long long b = 1LterSystem.out.println (Objects.equals (b, (println)); / / result: true
In some cases, you can directly use the = sign to judge:
Integer a = 1terlong b = 1LterSystem.out.println (adept roomb); / / result: true
In addition to the fact that the Objects.equals method returns false directly because the two input parameter types are different, the equals of java's eight basic types of wrapper classes will have the same problem, which requires special attention.
Previously, if you directly use the equals method of the java base type wrapper class to determine equality.
Integer a = new Integer (1); long b = 1LterSystem.out.println (a.equals (b))
In idea, if you mouse over the equals method, the following prompt appears:
At this point, you know that the method is wrong, so correct it quickly. However, if you use the equals method of the wrapper class directly, one problem is that there may be a risk of null pointer exceptions.
If you use the Objects.equals method to judge equality, there is no error in idea.
In addition, I also tested findBug, sonar and other tools, and the inconsistency of the two parameter types of the Objects.equals method was not identified.
Guys, take a look at your code. Did you step on it?
Common pits are:
Compare the Long type with the Integer type, for example: the scenario of the user id.
Compare the Byte type with the Integer type, for example: the scenario of state judgment.
Compare the Double type with the Integer type, for example, the judgment scenario where the amount is 0.
These are all the contents of the article "Analysis of Objects.equals trampling examples in Java". Thank you for reading! I believe you will gain a lot after reading this article. The editor will update different knowledge for you every day. If you want to learn more knowledge, please pay attention to the industry information channel.
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.