So I've heard that if I compare 2 strings with == then I will only get true back if they both refer to the same object/instance. That's strings. What about Booleans?
Does == check for full equality in Booleans? - Java
It depends on whether you're talking about Booleans (the object wrapper, note the capital B) or booleans (the primitive, note the lower case b). If you're talking about Booleans (the object wrapper), as with all objects, == checks for identity, not equivalence. If you're talking about booleans (primitives), it checks for equivalence.
So:
Boolean a, b;
a = new Boolean(false);
b = new Boolean(false);
System.out.println("a == b? " + (a == b)); // "a == b? false", because they're not the same instance
But
boolean c, d;
c = false;
d = false;
System.out.println("c == d? " + (c == d)); // "c == d? true", because they're primitives with the same value
Regarding strings:
I've heard that if I compare 2 strings with == then I will only get true back if the strings are identical and they both refer to the same object/instance...
It's not really an "and": == will only check whether the two String variables refer to the same String instance. Of course, one String instance can only have one set of contents, so if both variables point to the same instance, naturally the contents are the same... :-) The key point is that == will report false for different String instances even if they have the same characters in the same order. That's why we use equals on them, not ==. Strings can get a bit confusing because of interning, which is specific to strings (there's no equivalent for Boolean, although when you use Boolean.valueOf(boolean), you'll get a cached object). Also note that Java doesn't have primitive strings like it does primitive boolean, int, etc.
If you have an Object use equals,
when not you can run in things like this.
(VM cache for autoboxing primitives)
public static void main(String[] args){
Boolean a = true;
Boolean b = true;
System.out.println(a == b);
a = new Boolean(true);
b = new Boolean(true);
System.out.println(a == b);
}
the output is TRUE and FALSE
When using ( == ) with booleans,
If one of the operands is a Boolean wrapper, then it is first unboxed
into a boolean primitive and the two are compared.
If both are Boolean wrappers,created with 'new' keyword, then their
references are compared just like in the case of other objects.
new Boolean("true") == new Boolean("true") is false
If both are Boolean wrappers,created without 'new' keyword,
Boolean a = false;
Boolean b = Boolean.FALSE;
// (a==b) return true
It depends if you are talking about value types like: int, boolean, long or about reference types: Integer, Boolean, Long. value types could be compared with ==, reference types must be compared with equals.
Related
My code did not give the correct result and I begin to troubleshoot and discovered a strange error, can someone explain this to me.
If I pick up the fields and doing this it becomes result1 == false and result2 == true, why?
MyClass m1 = new MyClass();
MyClass m2 = new MyClass();
Field[] fieldsFirst = m1.getClass().getDeclaredFields();
Field[] fieldsSecond = m2.getClass().getDeclaredFields();
for (int i = 0; i < fieldsFirst.length; i++) {
Field first = fieldsFirst[i];
Field second = fieldsSecond[i];
first.setAccessible(true);
second.setAccessible(true);
if(first.get(m1) instanceof Boolean)
{
boolean b1 = (Boolean)first.get(m1);
boolean b2 = (Boolean)second.get(m2);
//Here are the results
boolean result1 = b1 != b2; // false
boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2); // true
}
If I have:
public class MyClass {
private boolean myBoolean = true;
public boolean getMyBoolean()
{
return myBoolean;
}
public void setMyBoolean(booelan inBool)
{
myBoolean = inBool;
}
}
In
boolean result1 = b1 != b2; // false
you are comparing primitive values, as b1 and b2 result from unboxing conversion from Boolean to boolean.
In
boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2); // true
you are comparing references. The result of each get() is referencing a different object. As such, the != comparison is true.
Boolean is a wrapper around the primitive boolean.
a wrapper class wraps (encloses) around a data type and gives it an
object appearance. Wherever, the data type is required as an object,
this object can be used. Wrapper classes include methods to unwrap the
object and give back the data type.
Source: http://way2java.com/java-lang/wrapper-classes/
Just like with other objects, if you need to compare their values, you need to use .equals() and not the comparison operators.
Here:
boolean b1 = (Boolean)first.get(m1);
boolean b2 = (Boolean)second.get(m2);
You are converting the Boolean to boolean. This is called as unboxing conversion which is a part of the AutoBoxing Conversions. These are called Auto because Java automatically does that conversion for you; even if you get rid of the cast.
Hence, you are comparing their primitive values.
Since the primitive values are the same, your comparison evaluates to true. Hence, false
Here:
boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2);
You are comparing the references of the two objects. Since they are stored in different memory locations, the result of the comparison is true. Intuitive, isn't it? Different object, different memory location?.
If you really need to compare the values of two objects, use the equals() methods. In case of Wrapper objects however, close your eyes, unbox them to their primitive values and then compare.
Just like Josh Bloch suggests in Effective Java: Comparing Wrappers? Unbox the suckers!!
Just more from Effective Java, comparison operators work in case of Wrapper class if they have a greater than or less than sign attached to them. <, <=, >, >= yield the correct result even if you do not unbox. == and != do not yield correct result
The comparation boolean result1 = b1 != b2 is a primitive value comparation, so you can use operators like == or !=.
The comparation boolean result2 = (Boolean)first.get(m1) != (Boolean)second.get(m2) is an object comparation, so you are not comparing values, but references. You should compare them by using equals()
Like boolean result2 = ((Boolean)first.get(m1)).equals((Boolean)second.get(m2))
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference Between Equals and ==
For example, if I have
MyClass foo = new MyClass();
MyClass bar = new MyClass();
if (foo == bar) {
// do something
}
if (foo < bar) {
// do something
}
if (foo > bar) {
// do something
}
how do foo and bar get compared? Does Java look for .compareTo() methods to be implemented for MyClass? Does Java compare the actual binary structure of the objects bit for bit in memory?
Very simply the arithmetic comparison operators == and != compare the object references, or memory addresses of the objects. >, and < and related operators can't be used with objects.
So ==, != is useful only if you want to determine whether two different variables point to the same object.
As an example, this is useful in an event handler: if you have one event handler tied to e.g. multiple buttons, you'll need to determine in the handler which button has been pressed. In this case, you can use ==.
Object comparison of the type that you're asking about is captured using methods like .equals, or special purpose methods like String.compareTo.
It's worth noting that the default Object.equals method is equivalent to ==: it compares object references; this is covered in the docs. Most classes built into Java override equals with their own implementation: for example, String overrides equals to compare the characters one at a time. To get a more specific/useful implementation of .equals for your own objects, you'll need to override .equals with a more specific implementation.
You didn't try it yourself, apparently, because <, >, <= and >= do not work on Objects.
However, == compares the left and right operand. When they are binary the same, it results in true. In the case of objects, in compares the pointers. So which means that this will only result in true if the Object is left and right the very same object in memory.
Other methods, like compareTo and equals are made to provide a custom method of comparing to different objects in memory, but which might be equal to each other (i.e. the data is the same).
In case of Strings, for example:
String str0 = new String("foo");
String str1 = new String("foo");
// A human being would say that the two strings are equal, which is true
// But it are TWO different objects in memory. So, using == will result
// in false
System.out.println(str0 == str1); // false
// But if we want to check the content of the string, we can use the equals method,
// because that method compares character by character of the two objects
String.out.println(str0.equals(str1)); // true
String.out.println(str1.equals(str0)); // true
No it doesn't. It compares whether the two variables are references to the same objects.
Unless you're dealing with types which are subject to autoboxing, such as Integer, you can't use > and < with objects at all.
In the case where you are using an autoboxed type, java doesn't look for specific methods, but will auto-unbox the variables, turning them into primitives - but this isn't the case for the equals operator. The == operator will always compare objects as references, even when comparing autoboxed objects:
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
if(i1 < i2) { // evaluates to false!
System.out.println("i1 is less than i2");
}
else if(i1 > i2) { // evaluates to false!
System.out.println("i1 is greater than i2");
}
else if(i1 == i2) { // evaluates to false!
System.out.println("i1 and i2 are equal");
}
else {
System.out.println("Um... well that's just confusingi");
}
It compares the reference value and will only return true if foo and bar point to the same object.
In Java, "==" compares the object identity. "new" is guaranteed to return a new object identity each time.
I'd actually love if "==" would call compareTo. Alas, it doesn't.
This question already has answers here:
How can I properly compare two Integers in Java?
(10 answers)
Closed 5 years ago.
I have the following code:
public class Test {
public static void main(String[] args) {
Integer alpha = new Integer(1);
Integer foo = new Integer(1);
if(alpha == foo) {
System.out.println("1. true");
}
if(alpha.equals(foo)) {
System.out.println("2. true");
}
}
}
The output is as follows:
2. true
However changing the type of an Integer object to int will produce a different output, for example:
public class Test {
public static void main(String[] args) {
Integer alpha = new Integer(1);
int foo = 1;
if(alpha == foo) {
System.out.println("1. true");
}
if(alpha.equals(foo)) {
System.out.println("2. true");
}
}
}
The new output:
1. true
2. true
How can this be so? Why doesn't the first example code output 1. true?
For reference types, == checks whether the references are equal, i.e. whether they point to the same object.
For primitive types, == checks whether the values are equal.
java.lang.Integer is a reference type. int is a primitive type.
Edit: If one operand is of primitive type, and the other of a reference type that unboxes to a suitable primitive type, == will compare values, not references.
Integer objects are objects. This sounds logical, but is the answer to the question. Objects are made in Java using the new keyword, and then stored in the memory. When comparing, you compare the memory locations of the objects, not the value/properties of the objects.
Using the .equals() method, you actually compare the values/properties of objects, not their location in memory:
new Integer(1) == new Integer(1) returns false, while new Integer(1).equals(new Integer(1)) returns true.
ints are a primitive type of java. When you create an int, all that is referenced is the value. When you compare any primitive type in Java, all that is compared is the value, not the memory location. That is why 5 == 5 always returns true.
When you compare an Integer object to a primitive type, the object is cast to the primitive type, if possible. With an Integer and an int this is possible, so they are compared. That is why Integer(1).equals(1) returns true.
What you'll use new Integer(1) to create new object, it creates a totally different object each time even though it has the same value. The '==' checks if the objects are same, not data values. In your case, you could have checked the value as follows :
if(alpha.intValue() == foo.intValue()) {
//
}
Integer == int here auto boxing applied ( so Integer converted to int before comparision) so true.. but Integer == Integer here object comparison so as reference are different so false..
First example:
Using the == operator between objects checks for reference equality, and since you are comparing two different objects they do not equal.
Second example:
When using the == between a wrapper type (Integer, Long, etc.) and a numeric type (int, long, etc.) the wrapper type is unboxed and the equality check is done between the two primitive numeric types (I.e. between int and int). The unboxing is part of binary numeric promotion, read more here: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
Consider two references of type Integer that call the static factory method valueOf as shown below:-
Integer a = Integer.valueOf("10");
Integer b = Integer.valueOf("10");
Considering that Integer is immutable, is it ok to compare a and b using == instead of using equals method. I am guessing that the valueOf method makes sure that only one instance of Integer with the value 10 is created and a reference to this instance is returned for every Integer created with a value 10.
In general, is it ok to compare two references of an immutable class that are created using a call to the same static factory method by using == instead of equals?
Edit:
The Integer class was used just as an example. I am aware thar Intgers upto 127 will return true if they are compared using ==. What i need to know is that when l create my own immutable class, say MyImmutable with a method create() that will ensure that no duplicate MyImmutable objects are created, will it be ok if I compare 2 MyImmutable references created using the create method by using == instead of equals.
No, that's not safe in general. The == operator compares the references, not the values.
Using == happens to work for integers between -128 and 127, but not for other integers. The following code demonstrates that == won't always work:
Integer a = Integer.valueOf(10);
Integer b = Integer.valueOf(10);
System.out.println(a == b);
true
Integer c = Integer.valueOf(1000);
Integer d = Integer.valueOf(1000);
System.out.println(c == d);
false
See it working online: ideone
The explanation for this behaviour lies in the implementation of Integer.valueOf:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
source
Not also that the standard requires that boxing integers for small inputs (-128 to 127) gives objects with equal references.
5.1.7 Boxing Conversion
If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
However the standard makes no such guarantees for integers outside this range.
In general, is it ok to compare two references of an immutable class that are created using a call to the same static factory method by using == instead of equals?
As shown above, it won't work in general. But if you ensure that two immutable objects with the same value always have the same reference, then yes, it could work. However there are some rules you must follow carefully:
The constructor must not be public.
Every object you create via the static method must be cached.
Every time you are asked to create an object you must first check the cache to see if you have already created an object with the same value.
== and equals() is fundamentally different.
You should read this post for more details:
Difference between Equals/equals and == operator?
It has nothing to do with immutable objects.
If your factory method returns the same object for equal inputs, it's safe to compare them with ==. For example String.intern works this way. Enums are also could be compared with ==. But Integer.valueOf returns the same object only for -128 ... 127 range (in default configuration).
Integer.valueOf(127) == Integer.valueOf(127)
but
Integer.valueOf(128) != Integer.valueOf(128)
Generally speaking you should use equals method to compare any objects. Operator == could be used to improve performance, when there are small number of different values for object. I wouldn't recommend to use this method, unless you are 100% sure in what you are doing.
Immutability and equality do not necessarily have something to do with each other. == compares for reference equality, that means, it compares if both variables point to the very same instance of the object. Equality means that both objects share the same value. Immutability now means that you can not alter an object after its construction.
So, you might have two immutable obejcts, that represents the same value (meaning, they are equals so that a.equals(b) returns true) but that are not the same instance.
I have a little example for you here:
public class MyPoint {
private int x;
private int y;
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof MyPoint))
return false;
MyPoint p = (MyPoint) obj;
return this.x == p.x && this.y == p.y;
}
/**
* #param args
*/
public static void main(String[] args) {
MyPoint p = new MyPoint(2, 2);
MyPoint q = new MyPoint(2, 2);
MyPoint r = q;
System.out.println(p == q);
System.out.println(p == r);
System.out.println(q == r);
System.out.println(p.equals(q));
System.out.println(p.equals(r));
System.out.println(q.equals(r));
}
}
The output is:
false
false
true
true
true
true
MyPoint is immutable. You can not change its values / its state after is has been initialized. But, as you can see, two objects of myPoint might be equal, but they might not be the same instance.
I think what you have in mind is some kind of flyweight pattern, where only one object exists for every possible state of the object. Flyweight also means commonly that those obejcts are immutable.
They are not the same object, so == will not be true. With objects, be safe and use equals().
Why does the code below return false for long3 == long2 comparison even though it's literal.
public class Strings {
public static void main(String[] args) {
Long long1 = 256L + 256L;
Long long2 = 512L;
Long long3 = 512L;
System.out.println(long3 == long2);
System.out.println(long1.equals(long2));
}
}
Long is an object, not a primitive. By using == you're comparing the reference values.
You need to do:
if(str.equals(str2))
As you do in your second comparison.
Edit: I get it ... you are thinking that other objects act like String literals. They don't*. And even then, you never want to use == with String literals either.
(*Autobox types do implement the flyweight pattern, but only for values -128 -> 127. If you made your Long equal to 50 you would indeed have two references to the same flyweight object. And again, never use == to compare them. )
Edit to add: This is specifically stated in the Java Language Specification, Section 5.1.7:
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f, or an int or short number between -128 and 127 (inclusive), then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.
Note that long is not specifically mentioned but the current Oracle and OpenJDK implementations do so (1.6 and 1.7), which is yet another reason to never use ==
Long l = 5L;
Long l2 = 5L;
System.out.println(l == l2);
l = 5000L;
l2 = 5000L;
System.out.println(l == l2);
Outputs:
true
false
You could also get the primitive value out of the Long object using:
str.longValue()
If you want to do
str3==str2
do like this..
str3.longValue()==str2.longValue()
This serves your purpose and much faster because you are comparing two primitive type values not objects.
Here Long is a Wrapper class so the below line will compare the reference not the content.
long3 == long2
its always better to compare with ** .longValue() ** like below
long3.longValue() == long2.longValue()
If we use in-build equal() method that also will do the same thing with null check.
long3.equals(long2)
Below is the internal implementation of equals() in java
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}