United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6578574 : short should convert to Integer under JLS 5.2

Details
Type:
Enhancement
Submit Date:
2007-07-10
Status:
Open
Updated Date:
2014-07-31
Project Name:
JDK
Resolved Date:
Component:
specification
OS:
windows_xp
Sub-Component:
language
CPU:
x86
Priority:
P4
Resolution:
Unresolved
Affected Versions:
6
Targeted Versions:

Related Reports
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
1.6.02
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Server VM (build 1.5.0_07-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows XP SP2
Ubuntu 6.04
SunOS 5.10 Generic_118833-24 sun4v sparc SUNW,Sun-Fire-T200


A DESCRIPTION OF THE PROBLEM :
if the switch statement is changes to be an "Integer" wrapper type, the non-int case statements fail to compile. if the switch statement is of type "Character", "Byte" or "Short" all works fine. I posted this problem on different websites. I got no answer. people guess that it is a bug. i am playing around for the SCJP exam, so the weird combination in this switch test is just for "playing". the results are not as I would expect them to be.

when all the wrappers except of "Integer" work (it works when changed to primitve "int") it seems like a bug to me.  e.g. "Short" should also not be assignable to "Byte". So how _exactly_ are the steps the compiler takes to resolve the problem. Other compilers e.g. Eclispe internal one says all cases are ok. just the Sun compiler doesn't think it is ok!

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
try the code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
when all the wrappers except of "Integer" work (it works when changed to primitve "int") it seems like a bug to me.
ACTUAL -
compile failed for non-int switch "cases"

ERROR MESSAGES/STACK TRACES THAT OCCUR :
SwitchTest.java:21: incompatible types
found   : short
required: java.lang.Integer
      case sP: System.out.println("");
           ^
SwitchTest.java:22: incompatible types
found   : char
required: java.lang.Integer
      case 'n': System.out.println("");
           ^
SwitchTest.java:23: incompatible types
found   : byte
required: java.lang.Integer
      case bP: System.out.println("");
           ^
3 errors

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class SwitchTest
{

    public static void main(String[] args)
    {
        final int iP = 1;
        final short sP = 126;
        final byte bP = 2;
        Short sLw = 3;
        Byte bLw = 4;
        Character cLw = 5;
        Integer iLw = 6;
 
        // switch (cLw){ // works fine, just uncomment it
        // switch (bLw){ // works fine, just uncomment it
        // switch (sLw){ // works fine, just uncomment it
        switch (iLw) {  // the non-int cases FAIL - WHY?
            case sP:
                System.out.println("");
            case 'n':
                System.out.println("");
            case bP:
                System.out.println("");
            case iP:
                System.out.println("");
            case 127:
                System.out.println("");
        }
    }
}
---------- END SOURCE ----------

                                    

Comments
EVALUATION

Here's what the JLS have to say about it:

The type of the [switch] Expression must be char, byte, short, int, Character, Byte, Short, Integer, or an enum type (??8.9), or a compile-time error occurs.

[...]

All of the following must be true, or a compile-time error will result:

Every case constant expression associated with a switch statement must be assignable (??5.2) to the type of the switch Expression.



In this case we have that the switch variable has type 'Integer', which is legal. Then we have that the compiler generates an error when a case statement, whose constant is of type 'short' is added. The problem is that 'short' is not assignable - literally speaking' to Integer, as the only moves allowed by JLS 3rd 5.2 are:

*) 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.

So, if we apply boxing to 'short' we end up with Short which cannot then be converted to Integer by widening reference conversion. REassigning to spec for further evaluation.
                                     
2010-11-05
EVALUATION

As I noted in 6558543, boxing should be orthogonal to otherwise-legal widening/narrowing. I see no reason not to allow up-conversion from short, byte, etc to Integer, Long, et al. JLS 5.2 should allow: "a widening primitive conversion (5.1.2), ***optionally followed by a boxing conversion***". The switch code in 6578574 would then compile.
                                     
2010-11-08
Note that if assignment allows [widening primitive + boxing + widening reference], then behavior becomes ambiguous for things like short -> Number.  (Is the result a Short or an Integer?)  That would have to be sorted out somehow.
                                     
2014-07-31



Hardware and Software, Engineered to Work Together