Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can throw be used instead of break in a switch statement?

Can throw also be used to exit switch statement without using break keyword? Why use a throw instead of break?

switch(number)
{
    case 1:
        throw new RuntimeException("Exception number 1");
    case 2:     
        throw new RuntimeException("Exception number 2"); 
}
like image 216
Jerry Avatar asked May 16 '13 05:05

Jerry


2 Answers

There are two cases in which you could use a throw to interrupt the flow of a switch:

  1. Flow Control; in general, this is a bad practice - you don't want exceptional behavior deciding where your program decides to go next.

  2. Unlikely-but-plausible default case; in case you hit a condition in which reaching the default should be impossible, but happens anyway. Somehow. Miraculously. Or, if you have strict coding standards, which mandate that switch statements have a default case.

    Example:

    public class Test {
        public static enum Example {
            FIRST_CASE,
            SECOND_CASE;
        }
        public void printSwitch(Example theExampleCase) {
            switch(theExampleCase) {
                case FIRST_CASE:
                    System.out.println("First");
                    break;
                case SECOND_CASE:
                    System.out.println("Second");
                    break;
                default:  // should be unreachable!
                    throw new IllegalStateException(
             "Server responded with 724 - This line should be unreachable");
         }
    }
    
like image 138
Makoto Avatar answered Nov 11 '22 06:11

Makoto


I see some reasons for throw in a switch statement.

1st: not instead of a break but as the body of the default case. Consider the following example where a switch is defined on an enumeration:

pubic enum E {
  A,
  B
}

The switch as of the time as it is first written looks like:

E e = ...;
switch (e) {
  case A:
    ...
    break;
  case B:
    ...
    break;
  default:
    throw new IllegalStateException("Unknown enumeration value " + e);
}

The throw is a fallback for future extensions to the enumeration E.

2nd: Sometimes I have where small getter functions, for example in the Swing table model. There I use return instead of break;

public String getColumnName(int col)
{
  switch (col)
  {
    case 0: return "Column 0";
    case 1: return "Column 1";
    ...

This is for the sake of brevity or compactness. One may say that these returns break the control flow. This is true. However, I think that for compactness reasons it might be allowed here.

If you accept return instead of a break in this case you may accept throw too here.

Object[] x = ...; // get some array which is not null from a function which
                  // only returns arrays, e.g. OSGI services
switch (x.length)
{
  case 0: throw new IllegalArgumentException("No service defined");
  case 1: return x[0]; // return the only available service
  default:
    ... // evaluate all services and return the best matching one
    return x[...];
}
like image 24
Claude Avatar answered Nov 11 '22 07:11

Claude