Thứ Bảy, 5 tháng 4, 2008

No Java Switch on Long

Section 14.11 ("The switch Statement") of the Third Edition of the Java Language Specification lists the types that the Java switch statement can support switching on. The Java switch statement supports switching on byte, Byte, char, Character, int, Integer, short, Short, or an Enum. When I was first learning Java, it was somewhat surprising to me that Java supported these integral types (except Enum which was not available at that time!), but did not support long or Long. Switching on non-integral types did not make sense, of course, due to the inability to precisely compare non-integral types. However, it seemed like long should be a valid type to switch on as shown in the next code listing.


package longswitch;

/**
* This example demonstrates the switch statement.
*/
public class SwitchExample
{
public static void main(String[] arguments)
{
final long value = System.currentTimeMillis() % 5;
switch ( value )
{
case 1 : System.err.println("One");
break;
case 2 : System.err.println("Two");
break;
case 3 : System.err.println("Three");
break;
case 4 : System.err.println("Four");
break;
default : System.err.println("Default");
break;
}
}
}


When one tries to compile the above code, an error ("possible loss of precision") like that shown in the next image is encountered.



As the Java Language Specification pointed out, a compiler error did result from using one of the types (long) that was not listed in the specification.

The code below makes the compiler error go away and, in this simple case, there is probably no need to worry about any rounding or truncation that might occur in the conversion of the long to an int.


package longswitch;

/**
* This example demonstrates the switch statement.
*/
public class SwitchExample
{
public static void main(String[] arguments)
{
final long value = System.currentTimeMillis() % 5;
switch ( (new Long(value)).intValue() )
{
case 1 : System.err.println("One");
break;
case 2 : System.err.println("Two");
break;
case 3 : System.err.println("Three");
break;
case 4 : System.err.println("Four");
break;
default : System.err.println("Default");
break;
}
}
}


In practice, we rarely "need" to switch on a long and the ability to switch on an int or Enum are sufficient. In fact, especially before Enum was available, I would have liked the ability to switch on String more than on long. Of course, as I have blogged about before, some people insist you should never use the switch statement. The Scala language provides a switch-like match that does not use or require break statements (which Scala does not support). I think that switch statements can be a red flag indicating possible design problems, but I also reject the argument that they are always bad or always the worst possible approach to a particular problem.

Không có nhận xét nào:

Đăng nhận xét