About Java memory management [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Integer wrapper objects share the same instances only within the value 127?
I have a question about the memory management in Java.
When I try the following code:
Integer a = 1;
Integer b = 1;
System.out.println(a==b); // this gives "true"
However,
Integer a = 256;
Integer b = 256;
System.out.println(a==b); //this gives "false"
Why?
Thanks very much.

That is because "autoboxing" uses Integer.valueOf, and Integer.valueOf keeps a cache of Integer objects for small integer values. Here's what the JLS says:
"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." JLS 5.1.7.
When you use the == operator to compare a pair of Integer objects, it is actually comparing the object references. So your get true if boxing gave you the same cached Integer object, and false if it didn't. Note that the JLS guarantees this behaviour for the ranges stated, but it also permits an implementation of the valueOf method to cache a wider range of values.
The bottom line is that you should use equals(Object) to compare Integer objects ... unless you are really trying to test if they are the same object.
According to what I read, "Integer" should create an "object" in the heap, thus the two objects should be the same.
If your code explicitly does a new Integer(...), it is guaranteed to create a new Integer object. However, autoboxing uses Integer.valueOf(...), and that is where the caching behaviour is implemented.

You shouldn't use reference equality (==) for objects. It's printing true in your first example because the first 128 Integer objects are cached by the Integer class. Use .equals()

When the values greater than range of data representation, they are different object because they are wrapped. You are now coparing like object ids.
You are comparing objects' addresses

Related

Java : Boxing and using == [duplicate]

This question already has answers here:
Why Integer class caching values in the range -128 to 127?
(5 answers)
Closed 6 years ago.
Lets say i have something like
int a = 100;
int b = 100;
Integer c = (Integer) a;
Integer d = (Integer) b;
c == d results to true. Does that mean objects c and d point to the same Object in memory?
Can any one shed light here?
Do we create 2 objects c and d here? Are they different objects or same? == tells me that they are same objects.
I also read somewhere that casting doesn't create new objects. It's just a way of representing the same object. That makes sense if I am trying to cast lets say an Object to a Integer.
But what about this case, where there is no object in picture before (all we had is primitives) and we are trying to create Object c and d here?
Autoboxing works without casting. The reason you're seeing reference equality is because autoboxing internally calls Integer.valueOf() which caches certain values:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

Why does == work for int, double etc, but not String in java

I don't understand why the operator == won't work when comparing string, but it will work when comparing int, double, float, etc.
From what I understand, == determines if two entities are pointing to the same object.
In the following code, a == b returns true. Why?
int a = 10;
int b = 10;
if (a == b) {
// …
}
I don't understand why the operator "==" will not work for comparing string, but will for comparing int, double, float, etc. from what i understand, "==" determines if two entities are pointing to the same object.
The root of your misunderstanding is that the primitive values like 1 and false and 3.14159 are NOT objects. They are values that DO NOT have an object identity.
In Java there are two kinds of type:
Primitive data types ... for which == compares the values
Reference types ... for which == compares the object identity
a and b are have different reference in memory but this statement returns true.
Now you are confusing something else. a and b are actually variables. And yes, behind the scenes variables do have corresponding memory addresses.
However ... a == b DOES NOT compare the addresses the variables. It compares the content of the variables. And the content of the variables are primitive values that don't have an address.
i thought "==" compares reference?
For reference types (objects and arrays), the == operator compares references.
For primitive types, the == operator compares the actual values.
Think about it. You want 42 to be equal to 42 ... no matter how the numbers were generated.
And just to get back to String. Despite being "built in" to the Java language, the String type is a reference type (the class java.lang.String) and == compares it using reference type semantics; i.e. by comparing identity. This is a cause of considerable confusion for new Java programmers (hence the knee-jerk closure), but it is a perfectly logical if you understand the bigger picture.
Now, things do get more complex when we throw the wrapper types and boxing / unboxing into the mix. But that is beyond the scope of your question.
You are right when comparing strings, but that is because strings are Reference types. == test for the same reference, not on the value, on Reference types.
But types like int, boolean, long, char are primitive, or "value" types, not reference types. That is; the variable is indicating the actual value; not the reference to where the value is stored.
Note that there are versions of the above that are reference types; the versions with capitals: Int, Boolean, Long, Char. These represent 'boxed' versions of the primitives above, and == compares references with them.

in which cases equals() is similar to ==? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference Between Equals and ==
in which cases equals() works exactly like == operator?
It seems that they both act similar for primitive data types. Are there any other cases in which both of them act equal?
== compares the bits of reference for Object type so if you have reference to same Object it would be the case
For example
Integer for value -128 and 127 (inclusive) it caches (while autoboxing) the instance so it would be the case here for the mentioned range of value of Integer
For primitive data types, there is no equals() (because they are not objects, and have no methods).
The default implementation (in class Object) for equals() just does object identity check (i.e. the same as ==). So if a class does not override it, it will have the same result as ==.
The operator == will always compare references for objects, and the actual value for primitive types.
Note that an array of primitives like int[] is still an object!
String test1 ="test";
String test2 = test1;
System.out.println(test1 == test2);
System.out.println(test1.equals(test2));
Both will print -
true
true
In addition to primitives (which are a special case) == and equals() behave similarly for every case in which reference equality is the same as actual equality:
Interned Strings
Certain Integer references (normally between -128 and +127, but this is configurable, and it depends on how the instance was constructed)
Singletons
Instances of Object (and any other class that doesn't override equals())
Obviously, when in doubt, use equals()
The equals() method evaluates on hashCode comparisons. While == compares objects by reference.

The behaviour of equals() method in Java [duplicate]

This question already has answers here:
Weird Integer boxing in Java
(12 answers)
What is the difference between == and equals() in Java?
(26 answers)
Closed 9 years ago.
Consider the following Java code:
Object a = new Integer(2);
Object b = new Integer(2);
System.out.println(a.equals(b));
Object x = new Object();
Object y = new Object();
System.out.println(x.equals(y));
The first print statement prints true and the second false.
If this is an intentional behavior, how this helps programming in Java?
If this is not an intentional behavior, is this a defect in Java?
I'm going to answer your question with reservations, but you should know that you are hurting yourself if the intent of the question was to get you to learn and your solution was to ask StackOverflow. That aside...
This behavior is intentional.
The default equals() method on java.lang.Object compares memory addresses, which means that all objects are different from each other (only two references to the same object will return true).
java.lang.Integer overrides this to compare the value of the Integers, so two different Integers both representing the number two compare equal. If you used == instead, you would get false for both cases.
Standard practice in Java is to override the equals method to return true for objects which have the same logical value, even if they were created at different times (or even with different parameters). It's not very useful to have objects representing numbers if you don't have a way to ask, "do these two things represent the same value?".
Incidentally, and this is a tangent here, Java actually keeps a cache of Integer objects for small values. So sometimes you may get two Integer objects where even the == operator will return true, despite you getting them from two different sources. You can even get code that behaves differently for larger integers than it does for smaller, without having it look at the integral values!
This is intended behaviour.
Object.equals() considers the object identity (i.e. an object is only equal to itself), which is the only thing you can do for generic objects.
Integer overrides the method to depend on the integer value, since two Integer objects with the same value are logically equal. Many other classes also override equals() since it's a core mechanism of the standard API and a lot of functionaliy e.g. in the collections framework depends on it.
Why do are you puzzled by the behaviour anyway? Most people are only confused by the == operator not behaving like that (it works like Object.equals()).
The equals method in Java serves a specific purpose: it determines if the objects are logically equal, i.e. their content is the same, whatever that may mean in the context of each specific class. This is in contrast to the objects being the same: two different objects could be logically equivalent.
Going back to your example, a and b are different objects that represent the same logical entity - an integer value of 2. They model the same concept - an integer number, and integer numbers with the same value are identical to each other. a and b are, therefore, equal.
The x and y objects, on the other hand, do not represent the same logical entity (in fact, they do not represent anything). That's why they are neither the same nor are equivalent.
It is intentional, of course.
When comparing Integer objects, equals returns true if their values (in your case, 1) are equal.
Applied on different objects of type Object, it returns false.
x.equals(x)
would return true.
See also Object.equals() doc. By the way, consider using Integer.valueOf(2) rather than new Integer(2) as it reduces memory footprint.
One last funny thing Integer.valueOf(2)==Integer.valueOf(2) will return true but Integer.valueOf(2000)==Integer.valueOf(2000) will return false because in the first case you will receive twice the same instance of the Integer object (there is a cache behind) but not in the second case because the cache is only for values between -127 to 128

What is the difference between identity and equality in OOP?

What is the difference between identity and equality in OOP (Object Oriented Programming)?
identity: a variable holds the
same instance as another variable.
equality: two distinct objects can
be used interchangeably. they often
have the same id.
Identity
For example:
Integer a = new Integer(1);
Integer b = a;
a is identical to b.
In Java, identity is tested with ==. For example, if( a == b ).
Equality
Integer c = new Integer(1);
Integer d = new Integer(1);
c is equal but not identical to d.
Of course, two identical variables are always equal.
In Java, equality is defined by the equals method. Keep in mind, if you implement equals you must also implement hashCode.
Identity determines whether two objects share the same memory address. Equality determines if two object contain the same state.
If two object are identical then they are also equal but just because two objects are equal dies not mean that they share the same memory address.
There is a special case for Strings but that is off topic and you'll need to ask someone else about how that works exactly ;-)
Identity means it is the same object instance while equality means the objects you compare are to different instances of an object but happen to contain the same data.
Illustration (in java)
Date a = new Date(123);
Date b = new Date(123);
System.out.println(a==b); //false
System.out.println(a.equals(b)); //true
So a and b are different instances (different allocations in memory) but on the "data" level they are equal.
For instance,
In StackOverFlow:
identity: I am Michael, you are
sevugarajan, so we are not same.
equality: if we have same reputation
scores, we are equal in some ways.
In Java and similar languages which 'leak' the abstraction of a reference of an object, you can test whether two references refer to the same object. If they refer to the same object, then the references are identical. In Java, this is the == operator.
There is also an equals method which is used to test whether two objects have the same value, for example when used as keys of a HashSet (the hash code of equal objects should also be equal). Equal objects should have the same 'value' and semantics when used by client code.
Purer object-oriented languages do not have an identity comparison, as client code generally shouldn't care whether or not two objects have the same memory address. If objects represent the same real-world entity, then that is better modelled using some ID or key value rather than identity, which then becomes part of the equals contract. Not relying on the memory address of the object to represent real-world identity simplifies caching and distributed behaviour, and suppressing == would remove a host of bugs in string comparison or some uses of boxing of primitives in Java.
Think about the words "identical" and "equivalent". If two things are identical, they have the same identity; they are same thing. If they are equivalent, one can be substituted for the other without affecting the outcome; they have the same behavior and properties.
Identity: Two references to the same object (o1 == o2).
Equality: The method o1.equals( o2 ) returns true. This doesn't necessarily mean that the two objects contain (all) the same data.
In theory it's possible to override a method equals() to return false even for identical objects. But this would break the specification of Object.equals():
The equals method implements an equivalence relation on non-null object references:
It is reflexive: for any non-null reference value x, x.equals(x) should return true.
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
For any non-null reference value x, x.equals(null) should return false.
Identity concept is quite philosophical, that's why you shouldn't reconduce it just to references.
You can say that two identities are the same if a change to the first is reflected on the second and vice-versa. Of course this includes also sharing the same memory address but in general while identity is related to the attributes of the object, equality is used to check whenever two objects are identical, but this doesn't include identity.
The viceversa is quite obvious, if two items have the same identity they are also equal (in equality terms of being interchangeable).
For primitive types ( int , boolean , char, long , float ... )
== and != is equality test
and for Objects
== and != is identity test. [ it compares only the reference ]
equals method is used for equality test of Objects [ it can be overridden to compare specific attributes]
i found an excellent article on this
http://www.cs.cornell.edu/courses/cs211/2006sp/Lectures/L14-Comparison/L14cs211sp06.pdf
http://ocw.mit.edu/NR/rdonlyres/Electrical-Engineering-and-Computer-Science/6-170Fall-2005/D659DC53-FB1D-403C-8E35-2CAECBED266E/0/lec12.pdf
Quote
I like pigs. Dogs look up to us. Cats look down on us. Pigs treat us as equals. :D
Sir Winston Churchill
x == y is true only if there's the same object referenced by variables x and y.
x.equals(y) depends on the implementation of x.equals(), and is usually less strict that the above, as it compares the content of the object. (In Java, if x.equals(y), it must also be true that x.hashCode() == y.hashCode();)
Example:
Integer w = new Integer(3);
Integer x = new Integer(1);
Integer y = x;
Integer z = new Integer(1);
// all of these evaluate to true
y.equals(x) // it's the same object, of course the content is same
x.equals(z) // different objects, same content (`1`)
z.equals(y)
!w.equals(x); // the content is different (`3` vs `1`)
!w.equals(y);
!w.equals(z);
x == y // same object
z != x // different objects
y != z
w != x
Identical vs. Equal objects
Two objects are said to have identical states (deep equality) if the graphs representing their states are identical in every respect, including the OIDs at every level.
Two objects are said to have equal states (shallow equality) if the graphs representing their states are same, including all the corresponding atomic values. However, some corresponding internal nodes in the two graphs may have objects with different OIDs.
Example: This example illustrates the difference between the two definitions for comparing object
states for equality.
o2 = (i 2 , tuple, <a 1 :i 5 , a 2 :i 6 >)
o3 = (i 3 , tuple, <a 1 :i 4 , a 2 :i 6 >)
o4 = (i 4 , atom, 10)
o5 = (i 5 , atom, 10)
o6 = (i 6 , atom, 20)
In this example, the objects o1 and o2 have equal states (shallow equality), since their states at the atomic level are the same but the values are reached through distinct objects o 4 and o 5 .
However, the objects o1 and o3 have identical states (deep equality), even though the objects themselves are not because they have distinct OIDs. Similarly, although the states of o4 and o5 are identical, the actual objects o4 and o5 are equal but not identical, because they have distinct OIDs.
To add, identity is also known as referential check (references to objects, get it?) and equality as structural check by some authors. At the end of the day an object in memory abstract is just a map/table structure indexed at certain memory address. There can be one or many references (memory addresses) pointing to it. They all are referential-ly identical. When contents of same object is copied to another counterpart then both are structurally equal.

Categories

Resources