2

Do booleans auto-box to the same instance?

I have a little test that says they do, but I'm not going to stake anything on that. Is it guaranteed?

    @Test
    public void autoboxBooleans() {
        Multimap<Boolean, Integer> ids = HashMultimap.create();

        for (int i = 0; i < 10; i++) {
            Boolean rand = ThreadLocalRandom.current().nextBoolean();
            ids.put(rand, System.identityHashCode(rand));
        }

        System.out.println(ids); // {false=[453523494], true=[2024918163]}
    }

Note: This question talks about integers out of the range 0-127.

Michael Deardeuff
  • 10,386
  • 5
  • 51
  • 74
  • 1
    autoboxing makes use of the `valueOf()` methods on the classes of the respective primitives. in many cases these are implemented to return already allocated instances. however, you should _never_ rely on this behavior. – jtahlborn Jul 21 '19 at 01:26
  • @jtahlborn unless, that is, [the documentation of the specific valueOf method](https://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#valueOf(boolean)) allows you to rely on it. – Andy Turner Jul 21 '19 at 08:41
  • @AndyTurner sounds like it may depend on the version of the jvm (as the answers below indicate) – jtahlborn Jul 24 '19 at 15:13
  • It is probably worth asking: why do you need to know? Relying on identity is rarely the right thing to do, especially for objects whose origin is unclear. – Andy Turner Jul 24 '19 at 16:38
  • @AndyTurner I had to return millions of booleans in a generic interface and I didn't want useless garbage. I was wondering if I could avoid `return condition ? Boolean.TRUE : Boolean.FALSE` – Michael Deardeuff Jul 24 '19 at 17:36

2 Answers2

5

For Java 111, JLS 5.1.7 states this:

At run time, boxing conversion proceeds as follows:

  • If p is a value of type boolean, then boxing conversion converts p into a reference r of class and type Boolean, such that r.booleanValue() == p

[...]

If the value p being boxed is the result of evaluating a constant expression (§15.28) of type boolean, char, short, int, or long, and the result is true, false, a character in the range '\u0000' to '\u007f' inclusive, or an integer in the range -128 to 127 inclusive, then let a and b be the results of any two boxing conversions of p. It is always the case that a == b.

The JLS does not explicitly state that the <wrapperType>::valueOf method is used for autoboxing. In practice, a Java compiler typically does implement it that way, but it is an implementation detail, and could (in theory) change.

So ... apart from the "constant expression" case ... you should NOT rely on autoboxed boolean values being identical to the Boolean.TRUE or Boolean.FALSE object references2.


1 - Earlier versions of the JLS made a stronger statement about boxing. But this is clearly a deliberate change to the spec.

2 - Your application could take steps to manually box boolean values using Boolean::valueOf (or some other way). But that's a different scenario. And probably not recommended, since you have to ensure that you do this consistently.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
4

Note: This answer is correct for Java 7 and 8, Java 9-11 have a slightly different phrasing in the JLS.


Thanks to the comment by jtahlborn, I was able to research the answer.

JLS 5.1.7 for Java 7&8 says (emphasis mine)

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.

For what it is worth, the javadoc for Boolean#valueOf says

... If the specified boolean value is true, this method returns Boolean.TRUE; if it is false, this method returns Boolean.FALSE....

Michael Deardeuff
  • 10,386
  • 5
  • 51
  • 74