Vitaly Vlasov
Vitaly Vlasov

Reputation: 95

Why does this bit of code work in Java 7 and not Java 8?

I'm currently using IDE Eclipse Version: Neon.2 Release (4.6.2) and version java Version 8 Update 131. In this code, the IDE gives an error - "Type mismatch: can not convert from byte to Integer":

Integer i = (byte) 10;

But this code is correctly executed in IDE Eclipse Version: Indigo Service Release 2 and java Version 7. What essentially changed in the widening conversion mechanism in the 8th version of java, because I do not think it is related to the IDE version?

Upvotes: 2

Views: 214

Answers (3)

Stephan Herrmann
Stephan Herrmann

Reputation: 8178

Accepting the program was bug 362279 in ecj, which was fixed in 2011.

PS: why bother investigating bugs in ancient versions? You're missing 1419 bug fixes only in JDT/Core.

Upvotes: 6

Holger
Holger

Reputation: 298469

Your assignment would only work, if two conversions were made at once

  1. Widening from byte to int
  2. Boxing from int to Integer

Apparently, older Eclipse versions allowed this, which has been changed, whereas javac never allowed this (I tested Java 6 to Java 9).

To find out, what is the correct behavior, we have do refer to the specification:

5.2. Assignment Contexts

Assignment contexts allow the value of an expression to be assigned (§15.26) to a variable; the type of the expression must be converted to the type of the variable.

Assignment contexts allow the use of one of the following:

  • an identity conversion (§5.1.1)
  • a widening primitive conversion (§5.1.2)
  • a widening reference conversion (§5.1.5)
  • a boxing conversion (§5.1.7) optionally followed by a widening reference conversion
  • an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

Note that the combination we would need for the code is not within the list. We can derive from that list, that the following should work:

Number i = (byte) 10;

which is a boxing conversion from byte to Byte, followed by a widening reference conversion to Number.

or

Byte b = 42;
int i = b;

which is an unboxing conversion from Byte to byte, followed by a widening primitive conversion from byte to int.

Since (byte) 10 is a compile-time constant, we also have to consider

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.
  • 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.

from the same section.

This allows some interesting combinations like

Character c = (byte)10;

or

Byte b = 'x';

but none with a variable type of Integer


As said, the conversion from byte to Integer is not within the list, so the fact that older Eclipse versions allowed it, can be considered a bug that has been fixed in the newer version.

Upvotes: 7

Pallavi Sonal
Pallavi Sonal

Reputation: 3901

This is definitely not an issue with JDK, because on command line using the javac compiler, the code throws the same compiler error with both JDK 7 and JDK 8 -

error: incompatible types
Integer i = (byte) 10;
            ^

In fact , I have Eclipse Mars Release 4.5.0 and it gives me the same compilation error with JDK 7 and 8. I don't have the newer versions so haven't tested on those, but if it is not throwing compilation error on any of the releases with JDK 7 then it must be a bug with the eclipse compiler of that JDK version.

Upvotes: 7

Related Questions