Does autoboxing call valueOf ()?

I am trying to determine if the following statements are guaranteed:

((Boolean)true) == Boolean.TRUE ((Boolean)true) == Boolean.valueOf(true) ((Integer)1) == Integer.valueOf(1) 

I have always assumed that autoboxing is equivalent to calling valueOf() appropriate type. Each discussion that I saw in seems to support my assumption. But all I could find in JLS was the following ( §5.1.7 ):

If the entered p value is an integer literal of type int between -128 and 127 inclusive (§3.10.1) or a boolean literal true or false (§3.10) .3) or a character literal between '\u0000' and '\u007f' inclusive (§ 3.10.4), then let a and b be the result of any two transformations of the box into p . It always happens that a == b .

This describes an identical behavior similar to * with the valueOf() symbol. But there seems to be no guarantee that valueOf() actually called, that is, there could theoretically be an implementation that stores a separate dedicated dedicated cache for autonomous values. In this case, there may be an unequal identity between the cached autoboxes and the regular cached values ​​in the box.

The autoboxing tutorial for Oracle claims that li.add(i) compiled into li.add(Integer.valueOf(i)) , where i is int . But I do not know whether the textbook should be considered an authoritative source.




* This is slightly weaker than valueOf() , since this only applies to literal values.

+48
java boxing autoboxing
Jul 16 '15 at 3:44
source share
4 answers

At first I decided that your question was a hoax. What code does the compiler for autoboxing generate?

However, after your comment on @ElliottFrisch, I realized that it was different:

I know that the compiler behaves like this. I am trying to find out if this behavior is guaranteed.

For other readers, suppose “behaving this way” means using valueOf .

Remember that there are compilers for Java. To be "legal", they must follow the contract specified in the JLS . Therefore, as long as all the rules are followed, there is no guarantee that the internal implementation of autoboxing is implemented.

But I see no reason not to use valueOf , especially that it uses cached values ​​and is the recommended method for this article by Joseph D. Darcy.

+29
Jul 16 '15 at 3:59
source share
— -

As long as the language specification does not mention this, it is not guaranteed that autoboxing is equivalent to calling static valueOf methods. This is an implementation aspect, not part of the boxing conversion specification. An implementation is theoretically free to use a different mechanism if it complies with the rule you mentioned in JLS.

In practice, there are many Sun JDK error reports (for example, JDK-4990346 and JDK-6628737 ) that explicitly imply that when autoboxing was introduced in Java 5, the intention was for the compiler to rely on valueOf as specified in JDK-6628737 :

Static methods factory Integer.valueOf (int), Long.valueOf (long), etc. were introduced in JDK 5 for javac to implement the caching behavior required by the autoboxing specification.

But this is only for javac, not necessarily all compilers.

+16
Aug 01 '15 at 9:27
source share

Autoobject implemented using valueOf() ... in OpenJDK. If this is your implementation, read ... if not, skip below.

 ((Boolean)true) == Boolean.TRUE ((Boolean)true) == Boolean.valueOf(true) 

The Java documentation states that Boolean.valueOf() always returns Boolean.TRUE or Boolean.FALSE , so your link comparisons will succeed in these cases.

 ((Integer)1) == Integer.valueOf(1) 

In this particular example, as part of the OpenJDK implementation with default settings, this is likely to work because you selected the value <128, which is cached at startup (although this can be overridden as the arg command line). It can also work for large values ​​if it is often used enough for caching. If you are not working on “safe” assumptions about the Integer cache, do not expect reference comparisons to be equality.

Long , Short , Character and Byte way also implement this caching, but unlike Integer it is not configurable. Byte will always work if you are comparing autobox / valueOf() links, since obviously you cannot go beyond the range. Float and Double not surprisingly always creating a new instance.




Now, in purely general terms? See this JLS section - you MUST are assigned equal references for boolean and any int or char in the range from -128 to 127. There is no guarantee for anything else.

+2
Aug 07 '15 at 7:00
source share

The autoboxing tutorial for Oracle states that li.add (i) is compiled into li.add (Integer.valueOf (i)), where I am int. But I do not know whether the textbook should be considered an authoritative source.

I am running Oracle Java 1.7.0_72, it looks like it is using valueOf. Below is the code and bytecode for it. The bytecode indicates that it uses valueOf.

 public class AutoBoxing { /** * @param args the command line arguments */ public static void main(String[] args) { Integer x = 5; int i = x; System.out.println(x.toString()); } } Compiled from "AutoBoxing.java" public class testing.AutoBoxing { public testing.AutoBoxing(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_5 1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 4: astore_1 5: aload_1 6: invokevirtual #3 // Method java/lang/Integer.intValue:()I 9: istore_2 10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 13: aload_1 14: invokevirtual #5 // Method java/lang/Integer.toString:()Ljava/lang/String; 17: invokevirtual #6 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 20: return 

But I do not know what uses Open JDK. Let's try it.

-2
Jul 31 '15 at 17:36
source share



All Articles