1

I wrote a test code to check equality. I have checked Java doc and it says BigInteger is Immutable. Checking the documentation of the static factory method valueOf it looks like it returns the already cached immutable instance. So why does == returns false when its the cached instance.

Below is the Java doc for valueOf in BigInteger:

Returns a Big Integer whose value is equal to that of the specified long. This "static factory method" is provided in preference to a (long) constructor because it allows for reuse of frequently used BigIntegers.

The below code is going into infinite loop .

public static void main(String[] args) {
    while(true) {
        BigInteger a = BigInteger.valueOf(100);
        BigInteger c = BigInteger.valueOf(100);
        if (a == c) {
            break;
        }
 }
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Debapriya Biswas
  • 1,079
  • 11
  • 23
  • 3
    `==` tests for reference equality, `.equals()` test for value equality – azurefrog Jun 21 '16 at 18:07
  • Use `equal()` to check for equality. – Andrew Li Jun 21 '16 at 18:07
  • 2
    For primitive types `==` compares the value, but for objects it compares the references. – RaminS Jun 21 '16 at 18:07
  • 3
    This question is NOT a duplicate of the linked questions. It is about confusion over the meaning of "immutable", which just means the value cannot be changed. It does not mean that the JVM has to keep only one copy of every value you create. – Jim Garrison Jun 21 '16 at 18:10
  • This comparision should return true anyway, because the objects received from `valueOf` should be pooled, so the second call should return reference to the same object. – Jagger Jun 21 '16 at 18:14
  • Here is the [documentation](https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#valueOf%28long%29) for this method, the second call should return the reference to the same object. – Jagger Jun 21 '16 at 18:20
  • @Tunaki this is not a dup. Please read carefully as it has to do with mutable vs immutable, not `==` vs `equals()`. I've edited the title for clarity. – Jim Garrison Jun 21 '16 at 18:30
  • 3
    @JimGarrison I feel your edit changes the intent of the question. An immutable object is still an object and the question is inherently about the behaviour of the `==` between objects, when the OP would expect that operator to return `true` here. However, if we then focus on immutability, a duplicate would be http://stackoverflow.com/questions/279507/what-is-meant-by-immutable – Tunaki Jun 21 '16 at 18:41
  • @Tunaki this question was intended to learn the static factory method value of whether it is inline with the Java document . – Debapriya Biswas Jun 21 '16 at 18:47
  • Please edit your question to make that clearer. Include the parts of the javadoc which are relevant and explain why you think the snippet you provide agrees/disagrees with the javadoc. – Sotirios Delimanolis Jun 21 '16 at 18:54
  • Thanks for editing the question but now, it is clear that all answers have been invalidated. They do not cover that new question at all. – Tunaki Jun 21 '16 at 19:14
  • 1
    "it allows for reuse of frequently used BigIntegers" but the criteria by which "frequently used BigIntegers" are defined is not specified in the documentation. Just because the method could return the same instance doesn't mean it will. – Andy Turner Jun 21 '16 at 19:31
  • 1
    I would expect this code to work for 0/1 as "frequently used" values, I would not expect this check to succeed for anything else. – Alexei Levenkov Jun 21 '16 at 21:44
  • ISTM that this question is exactly about this "pooling", and demonstrates it doesn't actually happen. @Tunaki: this is not a duplicate. The meaning of `==` seems to be clear, but the question tests for *identity* (i.e. if the first value is cached and when a second BI with the same value is requested, if it returns the firts one or not), for which `==`is the right choice. – Rudy Velthuis Jun 22 '16 at 06:52

4 Answers4

8

Immutable means only that the value cannot change after instantiation.

Specifically, it does NOT mean the JVM has to ensure there's only one copy of each value you create. You can create many immutable objects having the same internal state but they are still distinct objects. Comparing these with == will return false while equals() will return true.

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
3

BigInteger is a reference variable, unlike int, or double, which are primitive variables. This means that you cannot use "==" as you can with ints or doubles. Instead, you must use .equals(), similar to how you would with a String.

Mr. DROP TABLE
  • 334
  • 2
  • 9
  • In this case `valueOf` by the second call should return the reference to the same object anyway. – Jagger Jun 21 '16 at 18:22
  • @Jagger `valueOf` doesn't specify any kind of caching behavior. It's _allowed_ to cache things, but it is in no way obligated to. – Louis Wasserman Jun 21 '16 at 18:42
  • @LouisWasserman Yep, you are right. For example this `BigInteger.valueOf(100L) == BigInteger.valueOf(100L)` returns `false` and this `BigInteger.valueOf(1L) == BigInteger.valueOf(1L)` returns `true`. – Jagger Jun 21 '16 at 18:43
  • 1
    @LouisWasserman It looks like from `1L` to `16L` the `valueOf` returns the same reference, so in this case `a == c` would return always `true`. – Jagger Jun 21 '16 at 18:46
0

See source of BigInteger:

// If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant

and MAX_CONSTANT is 16

mauhiz
  • 506
  • 5
  • 14
-1

== checks for the reference instead of actual content. For this reason == is usually used with primitive data type like int,float etc. Immutable means whenever you update a existing value it will not be modified but instead a new one will be created. So in your example even though both are physically same object their references value are different.

abhishekl
  • 55
  • 5