Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Question on autoboxing

 
Lukasz Mazurek
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Could somebody tell me why it works:



But this doesn't:



I check the description of Double class and it has only two methods valueOf:
valueOf(double d) and valueOf(String s) but not valueOf(int s)

Thanks
 
Sergej Smoljanov
Ranch Hand
Posts: 467
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello.
JLS 7: 5.5. Casting Conversion this may help
(JLS 8: 5.5. Casting Contexts - for java 8)
Table 5.2. Casting conversions to reference types
show that there is no conversion that make int become Double.
also as you can see

as well not compile.
Recommend read Chapter 5. Conversions and Promotions it will help answer question like this and about method invocation
 
Sergej Smoljanov
Ranch Hand
Posts: 467
10
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Can you figure why compiler error?
 
Lukasz Mazurek
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think I see it: according to table 5.2 in JLS, there is no boxing conversion from int to Double. Method m() expects Double but we provide int here (ends with compilation error) and then we try to assign int to Double variable (no boxing conversion - compilation error as well).

What is misleading for me is that if autoboxing calls Double.valueOf() and Double.valuieOf(10) will return a double and there is a possibility of boxing conversion from double to Double then why we can't provide int where Double is expected...

But I think I'll study JLS more carefully

Thanks, for the help. Appreciate that!

 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Lukasz Mazurek,

First of all, a warm welcome to CodeRanch!

Lukasz Mazurek wrote:Could somebody tell me why it works:

Let's start with a few important rules: If you have an integral literal, it's by default an int. If you have a floating-point literal, it's by default a double. When executing calculations Java uses a "standard" data type. When you are calculating with integers, the result of the calculation will be an int. If you are doing some calculation with floating-points (decimals), the result will be a double.

Now let's have a look at your first code snippet10 is clearly an integral literal, so its data type is int. As you already have discovered in the javadoc of the Double class, there are only two valueOf methods: valueOf(double d) and valueOf(String s). Because an int fits implicitly into a double, the int is automatically widened into a double and the valueOf(double d) method is executed. So that statement compiles successfully.

Moving on the your second code snippetLet's start with another important rule: You can't have a List (and/or ArrayList) of primitive data types, you can only have a List (and/or ArrayList) of objects. Luckily for us, the Java API has for every primitive data type a primitive wrapper class (e.g. int -> Integer, float -> Float, and so on). You can find more detailed information in this topic.

So nothing wrong with the first line. You created a list of Doubles (and not doubles). And using the diamond (introduced in Java 7) that line and this line are equivalentNow your second line of code produces a compiler error for two reasons: the first one is really obvious (and probably unintentional): reference variable l is not defined So let's fix this issue firstNow there's still a compiler error in this line. In Java 5 autoboxing was introduced to the language. Thanks to autoboxing, a primitive data type is automagically converted to an instance of the corresponding primitive wrapper class. From the 1st code snippet: 10 is an integral literal and thus its data type is int. When you add a primitive to a List (or other collection), autoboxing comes into play (because you can only have a List of objects, not of primitives). So thanks to autoboxing an int will be converted into an Integer. You write in your codeand the compiler converts this intoAnd although an int fits into a double, an Integer IS-NOT-A a Double. And that's why you'll get a compiler error: you try to add an Integer to a list of Doubles, which is not allowed!
There are several alternatives to solve this issue. Here are some of them:

And finally, this topic has a very extensive discussion about wrapper classes, autoboxing and using the == operator. It's definitely worth reading.

Hope it helps!
Kind regards,
Roel
 
Lukasz Mazurek
Greenhorn
Posts: 6
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for the thorough answer!

Let's start with another important rule: You can't have a List (and/or ArrayList) of primitive data types, you can only have a List (and/or ArrayList) of objects. Luckily for us, the Java API has for every primitive data type a primitive wrapper class (e.g. int -> Integer, float -> Float, and so on). You can find more detailed information in this topic.

Actually, the topic that you've mentioned raised my question

I forgot about the basics: in my example, 10 is an int and Java compiler knows that an int should be autoboxed into an Integer (and nothing else, in particular not into Double).
 
Winston Gutkowski
Bartender
Pie
Posts: 10571
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Lukasz Mazurek wrote:I forgot about the basics: in my example, 10 is an int and Java compiler knows that an int should be autoboxed into an Integer (and nothing else, in particular not into Double).

Which is what I would have said if I'd been quick enough.

The fact is that the whole thing would've worked fine if you'd supplied 10.0 (which IS a double).

But well done for working it out for yourself.

Winston
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Lukasz Mazurek wrote:I forgot about the basics: in my example, 10 is an int and Java compiler knows that an int should be autoboxed into an Integer (and nothing else, in particular not into Double).

That's really a very common mistake. And thus an all-time classic for the actual exam Many people think because an int fits into a double, an int can be converted into a Double (and/or an Integer IS-A a Double). But that's completely wrong! The compiler sees an int and thanks to autoboxing it can only be converted into an Integer. And an Integer IS-NOT-A Double, so although you can cast an int to a double, you can not cast an Integer to a Double (you'll get a compiler error if you try do so).
 
A.J. Côté
Ranch Hand
Posts: 417
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As Roel stated with more examples, this compiles fine, just specify that 10 is a double by appending a d (10d):


output:
10.0
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A.J. Côté wrote:output:
10.0

Hard to believe that this would be the output of the Autobox class. Pretty sure there will be no output at all
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic