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

Autoboxing with different primitive types

 
Felipe Kunzler
Ranch Hand
Posts: 35
3
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey there!

I've seen this assumption a couple times:

According to that, shouldn't line 3 compile?

And shouldn't this last line give an error?

What does actually happen when Java is trying to compile the code in such cases?

Thanks!
 
Scott Selikoff
author
Saloon Keeper
Posts: 4032
18
Eclipse IDE Flex Google Web Toolkit
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's because of the class it is promoted to. 2 would be promoted to Integer(2) but Integer cannot be cast to Double. It would be like casting String as Double. Therefore, the compiler throws an exception.
 
Henry Wong
author
Marshal
Pie
Posts: 22104
88
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Felipe Kunzler wrote:
According to that, shouldn't line 3 compile?



See section 5.2 of the JLS, which specifies implicit casting for assignments.

https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.2

Implicit casting from primitive int to the Double class is not one of the options mentioned by that rule.

Henry
 
Henry Wong
author
Marshal
Pie
Posts: 22104
88
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Felipe Kunzler wrote:
And shouldn't this last line give an error?

What does actually happen when Java is trying to compile the code in such cases?


Same rule. Halfway down. There is a special case for compile time constants to the wrapper class, in certain cases. And the primitive int (compile time constant) to the Short class is one of those cases.

Oh. And in reading your first question again... No. There isn't a primtive int (compile time constant) to the Double class as a supported case either.

Henry
 
Felipe Kunzler
Ranch Hand
Posts: 35
3
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
After quite a long time thinking I guess I understood.

I thought that because this happens when assigning a primitive to a wrapper class:

This should happen as well:

Turns out that just like Scott said, it is wrong, what the compiler actually tries to do is:

And regarding the case with Short, as described in the Java Spec (see in Henry's comment), it is an exception to the rule so it becomes:


Just to make sure that I had fully understood the concept. I wrote the following lines and tried to predict the outcome, got all of them right


A * means that the conversion happened according to the second part of the 5.2. Assignment Contexts spec.
Trying to assign a primitive float or double to a wrapper would result in the same output as long did (no special rules applied).

Please correct me if I'm not correct.

Thank you all!

 
Felipe Kunzler
Ranch Hand
Posts: 35
3
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By the way, are those kind of conversion between primitives and wrappers covered in the OCA 8 exam?

The silly ones like

If so, I'll mark them as important to review couple more times. But I don't remember seeing any of these kinds on my OCA 8 Study Guide.

Thanks again!
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Felipe Kunzler,

First of all, a warm welcome to CodeRanch!

Felipe Kunzler wrote:This should happen as well:

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 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).
There are many alternatives to change this code snippet and make it compile without errors. Can you find at least 3 different alternatives (without using methods from the Double class)?

Felipe Kunzler wrote:Please correct me if I'm not correct.

You are spot-on! Just one little question: is there a specific reason why you didn't include the Character wrapper class in the above overview as a char is also considered to be a numeric type

Let's see if you have fully understand the above. Which lines in this code snippet will give a compiler error? And why?

Hope it helps!
Kind regards,
Roel
 
Felipe Kunzler
Ranch Hand
Posts: 35
3
Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Roel, thanks for the warm welcome once again! haha

Roel De Nijs wrote:There are many alternatives to change this code snippet and make it compile without errors. Can you find at least 3 different alternatives (without using methods from the Double class)?

Would it be the following?

Roel De Nijs wrote:Just one little question: is there a specific reason why you didn't include the Character wrapper class in the above overview as a Character is also considered to be a numeric type

Just because I thought it would get too big with every single one, halfway through I realized that Long, Float and Double had the same result, but then I forgot to include Character again. (Just tried with Character and char once more just to make sure I got it!)

Roel De Nijs wrote:Let's see if you have fully understand the above. Which lines in this code snippet will give a compiler error? And why?


This one just blew my mind right now!

I've always wondered why this one works:

And this one doesn't:

Your example got me thinking, and I realized that it is because the compiler only auto downcast if it is a compile time constant, so the compiler can check if the size fits that type!
Therefore:
commenting about each line
line1: Error because the compiler cannot guarantee that i1 (runtime variable) fits in a short. The literal value 2_000 instead would be ok.
line2: Same reason, i2 is final but still runtime variable.
line3: Same here
line4: This one would work because it is compile time variable, thus, the compiler can check if the value fits in a short!
line5: Error, 32768 can't fit in a short.

Thank you so much Roel, this last one was extremely useful!
 
Roel De Nijs
Sheriff
Posts: 10662
144
AngularJS Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Felipe Kunzler wrote:Would it be the following?

Absolutely!

Felipe Kunzler wrote:This one just blew my mind right now!

That's one of the main reasons (besides having fun) why I'm hanging around in this forum: to blow people's mind

Felipe Kunzler wrote:Your example got me thinking, and I realized that it is because the compiler only auto downcast if it is a compile time constant, so the compiler can check if the size fits that type!

Most of the additional questions or pop quizzes have just one intention: to get people to think a little harder so they can improve their Java knowledge. So I'm happy to see you did exactly that And even more happy after reading your explanation, because it's 100% correct! Only if it's a compile-time constant, the compiler will know the value (hence it's name "compile-time constant" ) and therefore can decide if an explicit cast (by the developer) is required (compiler error) or not (no compiler error). And a primitive (and String) literal are implicitly compile-time constants as well. This topic discusses compile-time constants in more detail.

Felipe Kunzler wrote:commenting about each line
line1: Error because the compiler cannot guarantee that i1 (runtime variable) fits in a short. The literal value 2_000 instead would be ok.
line2: Same reason, i2 is final but still runtime variable.
line3: Same here
line4: This one would work because it is compile time variable, thus, the compiler can check if the value fits in a short!
line5: Error, 32768 can't fit in a short.

Almost a perfect score! All your explanations are spot-on, except for line3. The local variable i3 is definitely a compile-time constant, but its value is not in the range of a short and therefore this line doesn't compile. If you change the value to e.g. 20_000, line3 will compile without errors as well.

Hope it helps!
Kind regards,
Roel

PS1. I moved your comments outside the code snippet as some of the comments were quite long and it's better to not write long lines in your code snippet. Hope that's ok with you!
PS2. Have a cow for pondering about my additional questions and providing almost flawless answers. Well done!
 
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
Felipe Kunzler wrote:By the way, are those kind of conversion between primitives and wrappers covered in the OCA 8 exam?

In contrast to the OCA7 certification exam, the OCA8 certification exam has an exam objective concerning wrapper classes
OCA8 Exam Topics wrote:Develop code that uses wrapper classes such as Boolean, Double, and Integer.
As you can see this exam objective is (just like all others) very generally worded, so it's very hard to tell to what extent you need to know about wrapper classes.

Wrapper classes are a very popular topic on this forum and there are a few excellent topics about wrapper classes and related subjects like autoboxing and using the == operator. If you have a good, solid understanding of everything explained in this topic, this one and this one you'll be able to answer wrapper class related questions on the exam very confidently and (more importantly) flawlessly
 
Felipe Kunzler
Ranch Hand
Posts: 35
3
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Roel De Nijs wrote:
Almost a perfect score! All your explanations are spot-on, except for line3. The local variable i3 is definitely a compile-time constant, but its value is not in the range of a short and therefore this line doesn't compile. If you change the value to e.g. 20_000, line3 will compile without errors as well.!


Ohh I see, I didn't actually know all the rules of when a variable becomes a compile-time constant, found this topic very helpful to clear this doubt.

Roel De Nijs wrote:
As you can see this exam objective is (just like all others) very generally worded, so it's very hard to tell to what extent you need to know about wrapper classes.

Wrapper classes are a very popular topic on this forum and there are a few excellent topics about wrapper classes and related subjects like autoboxing and using the == operator. If you have a good, solid understanding of everything explained in this topic, this one and this one you'll be able to answer wrapper class related questions on the exam very confidently and (more importantly) flawlessly


I will certainly take a look in both topics!

Thank you so much for clearing all those doubts Roel! (And the cow )
 
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
Felipe Kunzler wrote:Ohh I see, I didn't actually know all the rules of when a variable becomes a compile-time constant, found this topic very helpful to clear this doubt.

That's indeed probably the best topic to learn about which requirements have to be met to have a compile-time constant. And in this topic (which I also mentioned in one of my previous posts) you'll find some illustrative code snippets about to be a compile-time constant or not to be a compile time constant
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic