Balaji Nandhu
Balaji Nandhu

Reputation: 29

Compare reference two character with same value in Java

We know that the Runtime Constant Pool in Java stores the following literals: 1) Integer 2) Long 3) Float 4) Double 5) String . Hence, where are the Boolean Literals and Character Literals stored??

Example:

Character c1 = 'a';
Character c2 = 'a';
System.out.println(c1==c2); //prints true

Since == compares references, does c1 and c2 share the same reference? (=Note that these literals are created such that they are the objects of the respective Primitive Wrapper Classes.

Upvotes: 0

Views: 250

Answers (3)

Stephen C
Stephen C

Reputation: 719239

We know that the Runtime Constant Pool in Java stores the following literals: 1) Integer 2) Long 3) Float 4) Double 5) String .

Actually, that is not quite correct. A correct statement is that in practice there is a separate runtime pool for autoboxed values for each of the types Boolean, Byte, Short, Character, Integer and Long.

These pools are NOT for literals ... because literals of the wrapper types do not exist1. The Java literals for these types are values of primitive types. (And in fact, there are no distinct literals at all for types byte or short ... according to the JLS.)

There are NOT autoboxing pools for Float and Double, despite what the javadocs for the respective valueOf methods seem to imply. The JLS does not require autobox caching for Float and Double, and the libraries do not implement it (at least in Java 6, 7, 8).

The other thing to note is that not all values produced by autoboxing will be in the respective pools. For instance, (by default) only Integer caches the values for -128 through +127.

Hence, where are the Boolean Literals and Character Literals stored?

The answer follows from the above:

  • There are no literals of type Boolean and Character.
  • Instances of Boolean and Character created by autoboxing may come out of the respective autoboxing pools.

And for your example:

Since == compares references, does c1 and c2 share the same reference?

That is correct. And it illustrates the previous point. The autoboxing pool for Character is required (by the JLS) to cache '\u0000' through '\u007f'.


Note that I left out String. The String pool is different because it is (primarily) for string literals. On the other hand, autoboxing is not defined for string values ... because string values don't have to contend with the primitive versus wrapper dichotomy.


1 - Sorry for being pedantic, but if you want to really understand these things and talk coherently to other people about them, it is essential to use the correct Java-specific terminology. To be strictly correct, a Literal is something that appears in the >>source code<< of a program. At runtime, the corresponding thing is a Value.

Upvotes: 2

user6232985
user6232985

Reputation:

Character c1 = 'a';
Character c2 = 'a';

as same as

Character c1 = 'a';
Character c2 = c1;

Both references pointing to the same object.In the second case that I created, c2 referring to c1, where c1 is also a reference variable that's pointing to the object 'a'.

More explanation about reference variables can be found here.

Also to be more precise, you are creating two reference variables in the Stack memory, nominally c1 and c2 but both of them pointing to the same object in the heap memory!

Upvotes: 0

hqt
hqt

Reputation: 30284

As you said, c1 and c2 share same object in heap so the comparison will be true. This is Java cache mechanism. All characters, integers that value in range -127 .. 127 will be cached. So Java will get cached value instead creating new one. That's why both objects share same references.

Character c1 = 'a';
Character c2 = 'a';  
Character c3 = new Character('a');  // force Java creates new object in heap 
System.out.println(c1 == c2); -> true 
System.out.println(c1 == c3); -> false

Here is another example for the same reason:

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);  // true
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i3 == i4); // false, out of cache range

You will meet another example for string, but on different mechanism:

String s1 = "stack";
String s2 = "stack";
String s3 = new String("stack");
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // false

All java string when creating will be allocated and stored in String Pool. When you create new string (in case of s2), Java will search in String pool if this string is already allocated somewhere or not. In case s3, we say to Java: "Hi, Java, please always create new one for me".

Summary, when comparing two objects, using compareTo method, when compare two primitive, you can use == operator. (just remind you old Java class).

Hope this help :)

Upvotes: 2

Related Questions