Win a copy of Modern JavaScript for the Impatient this week in the Server-Side JavaScript and NodeJS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Bear Bibeault
  • Junilu Lacar
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • salvin francis
  • Frits Walraven
Bartenders:
  • Scott Selikoff
  • Piet Souris
  • Carey Brown

type casting - return value

 
Greenhorn
Posts: 29
IntelliJ IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Do you have any idea why test2 compiles but test3 does not?

Murat



 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Murat Kutluer wrote:Do you have any idea why test2 compiles but test3 does not?


Yes! Try marking variable i in test3 as final and see what happens...
 
Murat Kutluer
Greenhorn
Posts: 29
IntelliJ IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Roel, I got it. The trick is compile-time constant.

 
Murat Kutluer
Greenhorn
Posts: 29
IntelliJ IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Roel,

What about this one? Both int and long are larger primite than short, but int works, long doesn't.

Murat

 
lowercase baba
Posts: 12893
63
Chrome Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What exactly does the compiler error say?  Believe it or not, they usually give you a pretty good idea what the problem is.
 
Murat Kutluer
Greenhorn
Posts: 29
IntelliJ IDE PHP Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It says "incompatible types: possible lossy conversion from long to short".

I wonder why we don't see an error message like "incompatible types: possible lossy conversion from int to short" for "short s = (int) 1;".
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Murat Kutluer wrote:The trick is compile-time constant.


Exactly! In this topic you'll find an explanation about what's a compile-time constant.
 
author
Posts: 23882
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

To give more detail regarding the first question... the return statement is defined by section 14.17 of the JLS... https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17

In that section, it is mentioned that how it is assignable is defined by section 5.2 of the JLS...  https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.2

And that is how we reach the compile time constant conclusion.


Regarding the second question... variable assignment conversions is simply defined by section 5.2 of the JLS. No need to give further detail here...

Henry
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Murat Kutluer wrote:What about this one? Both int and long are larger primite than short, but int works, long doesn't.


That's very simple: because you can't assign a long to a short (or int or byte) without using an explicit cast.

Let's have a look at what happens behind the scenes. Remember that the compiler is often a very friendly guy, but sometimes can be very picky Assume this statementWhen the compiler sees that statement he has to decide if he must complain (compiler error) or not. So he probably thinks something like: "Hey dude, you know every integer literal is by default of type int and you are trying to assign an int to a short without an explicit cast. That's not looking very good for you. But wait a minute, I don't offer any suffix (or other alternative) to create a short literal (like with L or l for a long) and 15 is within the range of short, so I am not gonna complain about this statement. Otherwise you always have to write short s1 = (short)15; and that's a lot of typing and clutters your code. I am such a friendly guy! ".

Now consider this statementAnd again the compiler has to make up his mind about what to do with this statement: "I know you know that an integer literal is by default of type int. And I know as well that you know I am happy to let it pass so you can save some key strokes, but 150_000 is not within range of short! Do I need to assign 0, 15, 150, 1500, 15000, or ... to s2? I really have no clue, so because I can't make this decision myself, I must create a compiler error for this statement. Sorry about that!"

Finally consider the following statementAnd here is what the compiler thinks about this statement: "What are trying to pull off here, dude? You explicitly tell me to handle this literal as a long literal by adding the L suffix (or the long cast as in your example. And then you want me to be ok about assigning a long to a short? That definitely won't happen! You explicitly want me to treat that literal as a long and a long can't be assigned to a short without explicit cast. Don't forget that allowing short s1 = 15; was a friendly gesture of me to save you some typing (and also because you can't create a short or byte literal). But now you have explicitly turned the literal into a long literal, so you have to face the consequences. Here is a big, fat, juicy compiler error!"

For the same reason, the following statement will also fail to compileAnd just for the record, the Java Language Specification is the only thing that matters for the compiler and this behavior is clearly mentioned in §5.2. Assignment Contexts

In addition, if the expression is a constant expression (§15.28) of type byte, short, char, or int:
* A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.



Finally I like to draw your attention to the following code snippetAlthough both statement will have the same result (a primitive long variable with a value of 15), there is a slight (but important) difference between both statements. On the first line the int literal is implicitely widened to long and that value is assigned to lo1. On the second line a long literal is simply assigned to lo2. And that seems a minor difference, but is very important when you have a literal value which is outside the range of int as you can see in this code snippetNow line1 and line2 will fail to compile! Your very good friend, the compiler, considers 15_000_000_000 as an int literal but 15_000_000_000 is outside the range of int (resulting in a compiler error). On line3 the compiler considers 15_000_000_000L as a long literal and 15_000_000_000 is within the range of long, so this statement compiles successfully. That's the short version of the explanation. If you want the more elaborate one, just read this topic

Hope it helps!
Kind regards,
Roel
 
Roel De Nijs
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Henry Wong wrote:Regarding the second question... variable assignment conversions is simply defined by section 5.2 of the JLS. No need to give further detail here...


Based on my previous post I beg to differ
 
    Bookmark Topic Watch Topic
  • New Topic