In the programming language "Java", "==" is supported as a comparison operator for equality, but when used when comparing ** reference types ** that are not ** primitive types ** such as String types It will be an unexpected processing result. The bottom line is that you should not use the equality operator "==" when comparing whether the values of ** reference types are equal. ** **
In this article, I'll write about why you shouldn't use equality operators when doing String type comparisons, and what happens if you do. However, this time the article focuses only on the String type, but this is also a general reference type.
Primitive types are types that represent the data itself and have no behavior for manipulating the data. You cannot assign null to a primitive type.
For example, there are the following types.
Unlike primitive types, reference types require the use of the new operator to create and assign instances (entities) to objects, and each type has its own type-specific behavior. You can assign null to the reference type.
For example, there are the following types. In addition, the manufacturer can define the types and processes required to process the application other than the following.
By the way, if you were studying a language that uses pointers, you probably already know it. For those who say "** Reference **" in the first place, it is recommended because it is described in detail in the following article. https://qiita.com/hys-rabbit/items/2e94c8722dc8f950e77c
First, consider the output result by looking at the following processing.
TestEquals.java
public final class TestEquals {
public static void main(String[] args) {
final String sequence1 = "test";
final String newSequence = new String("test");
System.out.println("Comparison with equality operator 1:");
System.out.println(sequence1 == newSequence);
}
}
Now, what is the result of comparing the same string "test" with the equality operator? At first glance, the same character strings are compared, so the comparison result is likely to be true. ** However, in the above case, the comparison result will always be false. ** **
Why do you get this result? This is because the comparison with the equality operator "==" determines ** whether the data is stored at the same address in memory **.
It's a technical story, so I won't go into details here, but it's important to ask what memory is. However, in this article, I will only introduce some recommended articles. If you can afford to study, you may want to take a look.
** Java heap memory management mechanism ** https://www.atmarkit.co.jp/ait/articles/0504/02/news005.html
** Memory as seen by the program ** https://qiita.com/shinpeinkt/items/55c0d30754482e8235b9
In other words, in the above case, the variable "sequence1" and the variable "newSequence" are stored in different areas in the memory, so if you compare with the equality operator, false will be returned.
Basically, the above understanding is sufficient for the equality operator, In some cases, please check them as well.
TestEquals.java
public final class TestEquals {
public static void main(String[] args) {
final String sequence1 = "test";
final String sequence2 = "test";
System.out.println("Comparison with equality operator 2:");
System.out.println(sequence1 == sequence2);
}
}
The difference from the first example is that the variable "newSequence" was initialized using the new operator, but the string "test" is simply assigned to the variable "sequence2". What will happen to the processing result in the above cases? Is it false? ** No, in the above case it will be judged as true. ** **
This is due to a Java feature, which I will briefly explain. If you initialize by assigning the character string "test" to one variable and then initialize by assigning the character string "test" to another variable in the same way, it will be managed in the same area on the memory. Java has built-in features that make adjustments as if they were. Therefore, in the above case, the processing result is true.
Now, let's touch on the equals method defined in the leading String class. As a reminder, use the equals method as follows:
TestEquals.java
public final class TestEquals {
public static void main(String[] args) {
final String sequence1 = "test";
final String sequence2 = "test";
System.out.println("Comparison with equals method 1:");
System.out.println(sequence1.equals(sequence2));
final String newSequence = new String("test");
System.out.println("Comparison with equals method 2:");
System.out.println(sequence1.equals(newSequence));
}
}
By comparing with the equals method, true is returned in both of the two patterns in the above example. Now then, who is the equals method defined in the String class and what kind of processing is defined?
The following code is the processing of the equals method defined in the String class.
String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = length();
if (n == anotherString.length()) {
int i = 0;
while (n-- != 0) {
if (charAt(i) != anotherString.charAt(i))
return false;
i++;
}
return true;
}
}
return false;
}
At first glance it may seem difficult, but if you look at how it works while disassembling it, it's a very simple implementation.
First of all, the comparison is performed by the equality operator, and true is returned if the references are equal. This is the case of initializing by directly assigning a character string to a variable as mentioned in the previous example.
Then, it will be the judgment process when the reference destination is different from the next block. First, it determines whether the instance of the object passed as an argument is of type String, and if it is not of type String, it returns false because it is completely different data in the first place. Next, if the argument object is of type String, it is verified character by character from the beginning to see if it is equal to the character string to be compared. Finally, if all the characters are equal to the comparison target, true is returned.
From the above, you can see that the equals method implemented in the String class covers all the weaknesses of the comparison with the equality operator we saw earlier.
If you're comfortable reading this far, you may have noticed that if the String class that uses the equals method becomes null, a NullPointerException will always occur. Therefore, as a Java user, you must follow the rules below.
--When using the eauals method, it must be in the form ** "constants other than null.equals (variables or constants)" **
That is, the implementer must ensure that the String class that uses the equals method is not null. Of course, depending on the implementation, there may be situations where it cannot be made a constant, but if you still guarantee the processing of the program, you should design it so that null does not enter.
I've written this for a long time, but how was it? I know some explanations are missing, but I hope this article will be of some help to those who have started studying programming in Java.
https://morizyun.github.io/java/type-primitive-reference.html --Java primitive and reference types https://qiita.com/hys-rabbit/items/2e94c8722dc8f950e77c --Java reference to understand in the figure https://www.atmarkit.co.jp/ait/articles/0504/02/news005.html --Java heap memory management mechanism https://qiita.com/shinpeinkt/items/55c0d30754482e8235b9 --Memory as seen from the program
Recommended Posts