This week's book giveaway is in the Agile and Other Processes forum.
We're giving away four copies of The Little Book of Impediments (e-book only) and have Tom Perry on-line!
See this thread for details.
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

Type casting byte to Integer compile error

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


Any ideas why first one works but second one fails?
 
Henry Wong
author
Marshal
Pie
Posts: 22119
88
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Murat Kutluer wrote:
Any ideas why first one works but second one fails?


It's a weird artifact of section 5.2 of the Java Language Specification...

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

That section of the specification does not list implicit casting followed by boxing (auto) as an option. And hence, the second case is a compile error.

As for the first case, interestingly, there is a clause that covers that. It is a bit further down on that section, and applies to compile time constants. And interestingly, it only applies to narrowing followed by boxing.
           
Henry
 
Daniel Cox
Ranch Hand
Posts: 147
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is no compiler error.
 
Murat Kutluer
Greenhorn
Posts: 22
IntelliJ IDE Java PHP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Henry,

I think you meant this one. As you said there is nothing about Integer and Long and Integer and Long generate compile error.


A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
  • Byte and the value of the constant expression is representable in the type byte.
  • Short and the value of the constant expression is representable in the type short.
  • Character and the value of the constant expression is representable in the type char.





  • Hi Daniel, there are compile errors on second and third lines. I checked it many times.
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Murat Kutluer wrote:Hi Daniel, there are compile errors on second and third lines. I checked it many times.

    That's strange. Your original code compiles just fine on my system. I'm using Eclipse with a Java 7 JDK.
     
    Murat Kutluer
    Greenhorn
    Posts: 22
    IntelliJ IDE Java PHP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I'm using JDK 8. I also checked it on online compiler.

    http://www.tutorialspoint.com/compile_java_online.php
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I just noticed that my Eclipse compiler configuration for problems with boxing and unboxing conversions was set to "ignore"
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Daniel Cox wrote:I just noticed that my Eclipse compiler configuration for problems with boxing and unboxing conversions was set to "ignore"

    After doing some digging, I found out that my Eclipse IDE allows the code to compile due to a bug in the Eclipse compiler. I’m using Eclipse Indigo with JDK 1.7 compliance. It has nothing to do with the configuration to flag boxing/unboxing code as a warning or error (by default, this is set to "ignore").
     
    Murat Kutluer
    Greenhorn
    Posts: 22
    IntelliJ IDE Java PHP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Have you tried the command line? I changed the JDK version to 7 of IntelliJ, I got the same result.
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Yes. I get a compiler error when I use the command line but no compiler error when I use my Eclipse IDE.

    In my Eclipse IDE, this code compiles just fine when it shouldn't.

     
    Murat Kutluer
    Greenhorn
    Posts: 22
    IntelliJ IDE Java PHP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It is weird to see that Eclipse works different than JDK.
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It does happen. Eclipse doesn't use javac. It uses its own special compiler that is able to compile code as you type code. This webpage discusses autoboxing issues in Eclipse 3.4 (JDK compliance 1.5) - autoboxing code that doesn't compile in javac does compile in Eclipse 3.4 (JDK compliance 1.5).
     
    prateek shaw
    Ranch Hand
    Posts: 32
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
    Byte and the value of the constant expression is representable in the type byte.
    Short and the value of the constant expression is representable in the type short.
    Character and the value of the constant expression is representable in the type char.



    Thanks everyone for information, However i would like to add some point here.

    1-Integer , Short , Byte and Long all the wrapper classes and all are child of Number class.But they are not related each other. (i do not know why ?)
    2-And as all know all the whole number operation perform on int or long type. so it mean they automatically promoted to higher level (compiler does this task.).
    3-As long as it is primitive type operation it is easy to understand and remember , example lineA: this will not compiler error incompatible types: possible lossy conversion from int to byte.
    lineB: This will also work , because of final special modifier.

    4-And char is work differently , since it whole positive integer therefore you can directly assign value to char variable.
    5-Let see the Auto boxing and unboxing line1: incompatible types: Integer cannot be converted to byte. this mean the compiler will not Convert Integer Object to byte primitive type. it can only convert to int primitive type. It is because of point 1. There is no relationship between wrapper class however primitive type has some relation.
    line2: This line also not compile. ideally i thought this should compile , because wrapper class are immutable . once you declare you can not change them. However it does not work.
    line3: this compile and run.
    line4: this will not work ,let understand this i will converted to int type without any issue, but you can not able to convert int primitive to Byte class.  no relation.
    line5: this will work without any issue.
    line6: this will work because 100 is byte and byte will automatically converted to Byte object.
    line7: this will compile . Since i is Integer which is sub class of Number so you can convert to Number and Number is also sub class of Byte so downcast as well. Same as any object which you promote to Object class.
    but in run time it will throw error.
    java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Byte
            at IntExample.main(IntExample.java:8)
     
    Henry Wong
    author
    Marshal
    Pie
    Posts: 22119
    88
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    First, read this topic regarding compile time constants, as I will be referring to it...

    https://coderanch.com/t/454384/java/java/compile-time-constant

    prateek shaw wrote:
    3-As long as it is primitive type operation it is easy to understand and remember , example



    Two issues. One. "Easy to understand and remember" is relative. What is easy for someone may not be for another. This isn't really clear as a definition.

    And two... "because of final special modifier" isn't correct. It is possible to have the final specifier, and for it to still not work.

    Anyway, this works because section 5.2 (see above) has a section allow for compile time constants. And in this example, the expression is a compile time constant (see included link for details).

    Henry                           
     
    Henry Wong
    author
    Marshal
    Pie
    Posts: 22119
    88
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    prateek shaw wrote:


    This line doesn't compile because the right hand side expression is not a compile time constant (as of the latest version of the JLS, wrapper classes are not treated as compile time constants). And since it is not a compile time constant, it can't use the special clause of section 5.2 to be implicitly narrowed from an int to a byte.

    Henry
     
    Henry Wong
    author
    Marshal
    Pie
    Posts: 22119
    88
    C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    prateek shaw wrote:


    Line 7 is actually not clear, as you did not show the declaration and initialization of the i variable. However, I will speculate that the variable is not a compile time constant, and hence, it is why line 7 does not compile. If the variable had been a compile time constant, then line 7 should compile (and work) fine.

    Henry
     
    Ganesh Patekar
    Bartender
    Posts: 696
    23
    Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Oracle Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Henry Wong wrote:
    prateek shaw wrote:


    Line 7 is actually not clear, as you did not show the declaration and initialization of the i variable. However, I will speculate that the variable is not a compile time constant, and hence, it is why line 7 does not compile. If the variable had been a compile time constant, then line 7 should compile (and work) fine.

    Henry
    I think on line no 7he mistakenly typed i instead of i1, where i1 is Integer i1= 100; If that is the case then although i1 is declared final It will not compile because can not cast from int to Byte

    prateek shaw wrote:
    I assume It is i1 not i then It will compile but will give runtime exception ClassCastException says Integer cannot be cast to Byte.
     
    prateek shaw
    Ranch Hand
    Posts: 32
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Henry Wong for your feedback totally appreciated.

    This line doesn't compile because the right hand side expression is not a compile time constant (as of the latest version of the JLS, wrapper classes are not treated as compile time constants). And since it is not a compile time constant, it can't use the special clause of section 5.2 to be implicitly narrowed from an int to a byte.


    Thanks for clarification. This is new information for me.
     
    francisco de feudis
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi for all, sorry if I resume this old topic but there's something I don't understand.



    A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
    Byte and the value of the constant expression is representable in the type byte.
    Short and the value of the constant expression is representable in the type short.
    Character and the value of the constant expression is representable in the type char.


    Is there any reason for this or should I learn it as a simple rule? Why the types Integer and Long are not allowed with narrowing + boxing conversion?
    Thanks
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    francisco de feudis wrote:Is there any reason for this or should I learn it as a simple rule? Why the types Integer and Long are not allowed with narrowing + boxing conversion?

    Hello francisco de feudis. I have summarized the rules below.

    The rules for autoboxing a primitive to a Double, Float or Long are:
    • Only a double primitive can be autoboxed to a Double
    Double d = 1D; // compiles
    • Only a float primitive can be autoboxed to a Float
    Float f = 1F; // compiles
    • Only a long primitive can be autoboxed to a Long
    Long l = 1L; // compiles

    The rules for autoboxing a primitive to an Integer, Byte, Short or Character are:
    • An int primitive can be autoboxed to an Integer
    Integer i = 1; // compiles
    • A byte primitive can be autoboxed to a Byte
    byte b = 1;
    Byte b_ = b; // compiles

    • A short primitive can be autoboxed to a Short
    short s = 1;
    Short s_ = s; // compiles

    • A char primitive can be autoboxed to a Character
    char c = 1;
    Character c_ = c; // compiles


    Additional rules for autoboxing a primitive to an Integer, Byte, Short or Character are:
    • A byte, short, or char primitive can be autoboxed to an Integer if it is a compile-time constant
    short s = 1; // not a compile-time constant
    Integer i = s; // compiler error

    final short s = 1; // a compile-time constant
    Integer i = s; // compiles

    • An int, short, or char primitive can be autoboxed to a Byte if it is a compile-time constant and its value is within the byte range. This always happens via an implicit cast (narrowing primitive conversion) to byte followed by boxing to Byte
    char c = 1; // not a compile-time constant
    Byte b = c; // compiler error

    final char c = 1; // a compile-time constant
    Byte b = c; // compiles

    • An int, short, or byte primitive can be autoboxed to a Character if it is a compile-time constant and its value is within the char range. This may happen via an implicit cast (narrowing primitive conversion) to char followed by boxing to Character.
    byte b = 1; // not a compile-time constant
    Character c = b; // compiler error

    final byte b = 1; // a compile-time constant
    Character c = b; // compiles

    • An int, char, or byte primitive can be autoboxed to a Short if it is a compile-time constant and its value is within the short range. This may happen via an implicit cast (narrowing primitive conversion) to short followed by boxing to Short.
    byte b = 1; // not a compile-time constant
    Short s = b; // compiler error

    final byte b = 1; // a compile-time constant
    Short s = b; // compiles



    P.S.
    "may happen" because a byte primitive can never be narrowed.
     
    Murat Kutluer
    Greenhorn
    Posts: 22
    IntelliJ IDE Java PHP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This one is wrong, second line generate compile error.

     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for pointing that out Murat Kutluer. It’s my silly Eclipse compiler again. I’ve modified the rules below.

    The rules for autoboxing a primitive to a Double, Float, Long or Integer are:
    • Only a double primitive can be autoboxed to a Double
    Double d = 1D; // compiles
    • Only a float primitive can be autoboxed to a Float
    Float f = 1F; // compiles
    • Only a long primitive can be autoboxed to a Long
    Long l = 1L; // compiles
    • Only an int primitive can be autoboxed to an Integer
    Integer i = 1; // compiles

    Please ignore this rule
    • A byte, short, or char primitive can be autoboxed to an Integer if it is a compile-time constant
     
    francisco de feudis
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks for exhaustive reply Daniel Cox and Murat Kutluer.

    I'm still thinking about this lines regarding narrowing + autoboxing:



    I don't understand why only Byte, Short and Character are allowed to use narrowing + autoboxing, why Long and Integer are excluded.
    I just would know is behind this choice done by the Java language engineer (if it is a choice). There's something I don't know.


    A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:
    Byte and the value of the constant expression is representable in the type byte.
    Short and the value of the constant expression is representable in the type short.
    Character and the value of the constant expression is representable in the type char.


    Thanks again for the help.
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    francisco de feudis wrote:I don't understand why only Byte, Short and Character are allowed to use narrowing + autoboxing, why Long and Integer are excluded.

    The primitive types double, float, long and integer have their own literals (for example, 1D, 1F, 1L, 1).
    The primitive types byte, short, char do not have their own literals.

    The compiler uses a trick to allow you assign an int literal (like 1) to a byte, short or char variable without using an explicit cast. The compiler inserts an implicit cast for you. Any int, byte, short or char compile-time constant that is within range can be assigned to a byte, short or char without an explicit cast because the compiler inserts an implicit cast (if needed). Similarly, any int, byte, short or char compile-time constant that is within range can be assigned to a Byte, Short or Character without an explicit cast or an explicit boxing conversion because the compiler inserts an implicit cast (if needed) followed by an implicit boxing conversion.
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I noticed a typo in my last post. Java doesn't have an integer primitive type; it has an int primitive type.
     
    francisco de feudis
    Greenhorn
    Posts: 11
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks again for the reply Daniel Cox, I wonder at this point why the compiler can't do this:


    Integer I = (int)(byte) 1; //compile


    Here the cast to int is the implicit cast added by the compiler before to do the autoboxing.
     
    Daniel Cox
    Ranch Hand
    Posts: 147
    7
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    francisco de feudis wrote:I wonder at this point why the compiler can't do this:


    Integer I = (int)(byte) 1; //compile



    According to the rules, implicit casting applies only when autoboxing a primitive to a Byte, Short or Character. It doesn't apply when autoboxing a primitive to an Integer.
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic