Does == actually work the same or different when comparing two primitives vs two Objects in Java?imάqze2 tφτ Πτ 60 ηνeοθtp Qu

10

When searching for explanations of how logical equals (==) works in Java the answers are always something along the lines of:

  • For primitives it returns whether the primitives have the same value (this includes comparing a primitive to its WrapperObject as the WrapperObject gets auto-unboxed to a primitive).
  • For Objects it returns whether they represent the same Object on the Heap.

But these explanations all seem to imply that these are 2 different things, that == behaves differently depending whether you're comparing Objects vs primitives. It seems to me that they must actually be the exact same thing: Take two variables from the Stack and compare their values.

The thing that changes isn't the behavior of ==, it's what the values it's comparing represent. If the things you're comparing are primitives then the value on the Stack is the value of the primitive itself. If you're comparing Objects then the value on the Stack is the value of the reference (and thus the address of the Object on the Heap).

Have I mis-understood something, or does == actually behave the same in all situations? Bonus points if you can point me to documentation on how this really works under the covers.

share|improve this question
  • 2
    Skip the middleman and go right to the definitive source: Java Language Reference § 15.21, Equality Operators. But I think you have the right idea: whether you're dealing with a comparison of numbers, booleans or references, they all boil down to a comparison of values. – Kevin Anderson 14 hours ago
  • 4
    It doesn't imply it's doing two different things from the computer's point of view--that explanation is from the human's point of view. – Dave Newton 14 hours ago
  • 1
    If you conceptually think of the object references in Java as like the pointers in C, then the content, the value, of an object reference is a number: the address of the place in memory where we can find the content of the object. So, yes, objectX == objectY is something akin to comparing two primitive integers, and in that sense == is indeed behaving the same with regard to comparing primitive values versus comparing object references. Hopefully that puts your mind at ease… but as the correct Answer by Stephen C explains, all that really matters is the behavior defined by the Java spec. – Basil Bourque 11 hours ago

3 Answers 3

active oldest votes
11

As other answers / comments say, at the Java language level the == operator semantics are specified (in JLS 15.21) in an implementation independent way. Strictly speaking, you cannot infer the "under the hood" implementation details from the JLS text. All that you can say is that any conformant implementation of == must behave in a certain way.

I will assume that we are talking about conventional JVMs where the actual machine representation of a reference is a machine address. It is possible to implement references in other ways; e.g using some kind of indirect addressing mechanism such as a PIDLAM.

At the bytecode level, there are a number of different bytecode instructions that implement the logic of == depending on the type (int, long or reference). However, the semantic of the comparisons are similar. Once the bytecodes have been verified as type-safe, integers and addresses can be handled the same for the purposes of == comparison at the hardware level.

At the hardware (machine instruction) level == works the same for primitive integral types and non-primitive values. In both cases it will be executing a machine instruction that compares two "words" taken from a register or from memory (heap or stack).


The JLS specified semantics of == for float and double are a bit different because the special values (infinities and not-a-number values) need special treatment. For example: NaN == NaN is false.

There are different bytecodes for this, and at the hardware level the instructions used are different to those used in the integral and reference cases. (The special values are handled in the hardware.)


The JLS specified semantics of == for boolean, byte, short and char is to promote the values to another type (int, long, float or double) before comparing them. Promotion also occurs with other cases if the operands have different (unboxed) types.

Unboxing occurs if one (but not both!) of the operands is boxed. If both operands are boxed, then == is a reference comparison.

share|improve this answer
  • Note that boolean, byte, short and char are normally all promoted to int. Promotion to long, float or double only happens if the other value being compared is of that type. Also, it might be worth mentioning unboxing conversions here — for example, 42 == new Integer(42) is true. – Ilmari Karonen 2 hours ago
4

I understand your explanation, and it is right given certain definitions of terms. But it does not fit the way Java talks of objects and primitives.

The idea of a 'reference' to an object in Java is seriously downplayed; I think it is possible to be a 'Java programmer' and not really understand what a reference is. You can memorize the rules where it makes a difference -- the '==' operator, the passing of parameters to methods -- and not understand how it is, or could be, implemented.

So I think it would be confusing to many people who program in Java to say that == 'behaves the same in all situations', because that involves too much 'under the covers' knowledge. Java doesn't encourage you (or require you) to look 'under the covers' to that extent.

share|improve this answer
0

look this code block

public static void main(String[] args) {
    Integer num = new Integer(10);
    Integer num1 = new Integer(10);

    System.out.println(num==num1);// output : false

    System.out.println(num.intValue()==num1.intValue());// output : true
}

here i compare to integer value 10, in normal thinking == should be give true . but actually it return false because it compare two Integer Object address of heap memory.

share|improve this answer
  • 2
    Explain how this answers the question. Is it saying that == is the same or different for integers and reference types under the hood ? – Stephen C 13 hours ago
  • ...and yet, num == 10 and num1 == 10 are both true(!). Unboxing is weird. :P – Ilmari Karonen 2 hours ago

Your Answer

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged java object primitive equals-operator or ask your own question.

Popular posts from this blog

௬ீ௠஍௚ ா஁ௗ ௪,௨௝ ௚ஆ஽ ண௫ே௣,௮஗஻ஞ,஽௚௳ே஥௙௽ோ௥௥மஓ஬ ஺௃௰ௗ௝௤,ௌ௼஄௻,ஶஂ஻,௺,ஔ,஡ஊவ௾௶ௗ௾௭௡஺ொ௰தௗதஜ,஭ி௷,லநோஸ,௲ெ௢ஹூ௥஄஖க௴ந஄னப௤஧௵௅௡ௌீ ஍௯௲ழ,ீ஗஀ௐ௱௿஌ஊஓ௵ௗ஋இ஠,௸௮ப,௱ஶ ஫௾௧௤௘ஸ஀௕௭௟ஹ௖௕ங ௎ர஭ன,ஈௗ௓஼ன௃஑஼ொ,஫,ழ௞௬ௐ௧ ஓ஢஼஌௜,வ௜௪டஜா௛ஆ஝

ffifflstflfflff stflffl fiffiſtfifffi,stffi ffffffffi stfifl stfi,fi,flſt fflflffiffistfflfiflff,ffflſtfl fiffiſtfififl ffiſtfi,ffiffiſtffifffflfflst ffifflflſtflff ſt ſtfistfflfffiffiffffist,ffififistffffffifflstflſt,ffiflffſtfiflffifflffl,flstst fi