aspose file tools*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Why not Equal? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Why not Equal?" Watch "Why not Equal?" New topic
Author

Why not Equal?

Lydia Zhang
Greenhorn

Joined: Feb 24, 2002
Posts: 29
Hi guys,
I don't know why the following code doesn't work, aren't they same? x != y ???


Lydia
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61426
    
  67

When used with object references, the == operator is a test for identity rather than value equality.
So what you are testing in your code is whether x and y refer to the same object, which is clearly not the case.
In your example, to test the Integer instances for equality, you would use:

hth,
bear
[ June 14, 2002: Message edited by: Bear Bibeault ]

[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Alan Chong
Ranch Hand

Joined: Jun 05, 2002
Posts: 106
You didn't buy scjp exam books or download
tutorials I think. This principle is very basic.
You should get correct exam books or download
proper tutorials for scjp otherwise you will have
to buy a second voucher.
Deepali Pate
Ranch Hand

Joined: Mar 20, 2002
Posts: 114
Hi Lydia,
I think u are new to Java programming. let me help u out.
== is a operator and can be used to compare either primitive data types or objects of wrapper class. It returns true only when they point to the same memory block. Their value could be same but it has to point to same memory location to return true.
obj.equals(obj) equals() is a method in Object class overridden in all Wrapper classes and String class to compare values. So equals() method returns true when the values of the obj are same.
Remember equals() can be used only with object references and if invoked on prmitive types results in compile error.
Best way for u to get this clear is to write a code with primitive data types and objects of wrapper class and use both equals() method and == operator.
Deepali Pate
Ranch Hand

Joined: Mar 20, 2002
Posts: 114
Also i would like to add that whenever the keyword "new" is used it means that a new memory block is allocated so in your case it will return false. So whenever u use new keyword u can be sure == will return false
Also != is not as ==.
!= is as = that is assignment operator and == is for comparison.
Lydia Zhang
Greenhorn

Joined: Feb 24, 2002
Posts: 29
Thanks Bear, Alan, Deepali!!! Thank you so much for the clarify!
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120

So whenever u use new keyword u can be sure == will return false

I am sure you know, Deepali, but maybe Lydia doesn't, that the following returns true:

The method intern in the API explains it.


SCJP2. Please Indent your code using UBB Code
Deepali Pate
Ranch Hand

Joined: Mar 20, 2002
Posts: 114
Thanks a lot for that input Jose.
Can u please give me a small example program to explain what this statement means.
A pool of strings, initially empty, is maintained privately by the class String.
"When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned."
Thanks
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
This done to prevent the following code to create three different string objects containing the same information.

The second and third sentences don't create a new object, because string literals, strings computed from compile constant expressions and string objects that are interned, don't create a new string object if one with the same information already exists in the string pool.
Two reasons for this strategy:
a) Memory saving.
b) Speeding string comparation.
If two string objects are interned their references point to the same object in the string pool. Thefore they can be compared with == operator, much quickly than with the method equals.
Paul Villangca
Ranch Hand

Joined: Jun 04, 2002
Posts: 133
System.out.println(new String("hello").intern());

Doesn't this line still create a new String object containing "hello"?
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Originally posted by Paul Villangca:

Doesn't this line still create a new String object containing "hello"?

It does. Of course, that String has no reference to it so it is eligible for garbage collection immediately.
Corey


SCJP Tipline, etc.
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
No, Corey. The string object that corresponds to the string literal "hello" won't be eligable for garbage collection unless the class in whose contant pool is referenced is unloaded. I have already given you an example in Test and Test2 classes in this post
You can check that the string object is referenced by the constant pool by using javap -c MyClass
In the main method the bytecode that provides the argument to the String constructor is
ldc #4 (String "hello")
this bytecode loads a reference to the string object pointed by the entry number 4 in the constant pool.
This is the entry number 4 in the constant pool:

I have written a class file parser that is freely available here
You can check it out with it.
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
Look closely at that line of code, Jose:

The String literal "hello" does, indeed, have a reference to it from the constant table. However, notice the keyword "new." This code makes a brand new String object when it is executed that has the same contents as the String that is referenced from the constant pool. After this line is executed, there are 2 distinct String objects. Of course, they have the same contents. Try out this code snippet:

From that, you can see that a second String object is created. The difference is that one is made prior to execution of the program and is referenced from the constants table. The other one is created at run-time.
Corey
[ June 18, 2002: Message edited by: Corey McGlone ]
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120

The String literal "hello" does, indeed, have a reference to it from the constant table. However, notice the keyword "new." This code makes a brand new String object when it is executed that has the same contents as the String that is referenced from the constant pool. After this line is executed, there are 2 distinct String objects. Of course, they have the same contents.

two obvious for me to mention :roll:

The difference is that one is made prior to execution of the program and is referenced from the constants table. The other one is created at run-time.

Prior to the execution of the program? An object is created by the compiler?
No it cannot. The compiler places the content of the string literal within the constant pool itself.
This is the part of the constant pool that holds such information:

Again this output was taken from my small, lovely, good and cheap class-file parser.
The JVM replaces the entry number 4 in the constant pool by a reference to an interned string object containing the same information as the entry number 21 (shown above). This replacement is done the first time the JVM uses entry 4. The compiler is not able to create objects.
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
I'm sorry, I didn't mean for that to sound like the compiler was creating the object. However, the String information is stored in the constant table prior to the execution of that given line. Whichever way you look at it, there are still two distinct String objects.
Corey
Lydia Zhang
Greenhorn

Joined: Feb 24, 2002
Posts: 29
Thanks Jose and everybody for the clarify!
Tybon Wu
Ranch Hand

Joined: Jun 18, 2002
Posts: 84
I'm inclined to agree with Corey that a new String object will be created.
new String("hello").intern()
To me, this section of the statement is simply 2 statements combined in 1: create a NEW String object, then call the method intern() on this object. It doesn't matter if this is a String or what the intern method actually does, as long as it follows the form:
new MyClass(param).myMethod()


SCJP2
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
"Tybon"
Welcome to the JavaRanch! Please adjust your displayed name to meet the JavaRanch Naming Policy.
You can change it here.
Thanks, and again welcome to the JavaRanch!!
Jose Botella
Ranch Hand

Joined: Jul 03, 2001
Posts: 2120
I am sorry. I think I have messed up the subject: when saying that no object will be created by the third sentence. Obviously it will be, but I thought it was too obvious to consider the new string object created by new, regarding it will be immediately interned. The point I wanted to show is that the three references produced by each of the three expressions will point to the same interned string object.
My excuses again.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Why not Equal?