Unreachable Statement with Break

瘦欲@ 提交于 2019-12-20 03:42:30

问题


So I had a previous question but realized I posted the wrong offending code. I've marked the offending statements below.

What I am trying to do is set the precedence for each of the operators with that switch statement.

Maybe someone could point me in the right direction.

Just as a note, I AM running JAVA 7 so String Switch will work.

Code

opType.java

import java.io.*;

public final class opType {

   public static opType ADD = new opType( "Add" );
   public static opType SUB = new opType( "Sub" );
   public static opType MULT = new opType( "Mult" );
   public static opType DIV = new opType( "Div" );
   public static opType MOD = new opType( "Mod" );
   public static opType LPAR = new opType( "LParen" );
   public static opType RPAR = new opType( "RParen" );

   protected String name;

   private opType( String n )
   {
      name = n;
   }

   public String getName()
   {
      return name;
   }

Operator.java

public class Operator extends Token {

    protected opType val;

    public boolean isOperator() { return true; }
    public boolean isOperand() { return false; }

    protected int getPrec()
    {

        switch(val.getName())
        {
            case "LParen": 
            {
                return 0;
                break; //unreachable
            }

            case "RParen": 
            {
                return 0;
                break; //unreachable
            }

            case "Mult":
            {
                return 1;
                break; //unreachable
            }
            case "Div": 
            {   
                return 1;
                break; //unreachable
            }
            case "Mod": 
            {   
                return 1;
                break; //unreachable
            }
            case "Add": 
            {   
                return 2;
                break; //unreachable
            }
            case "Sub": 
            {   
                return 2;
                break; //unreachable
            }
        }

            return 0;
    }

    public static int compare( Operator a, Operator b )
    {
        if( a.getPrec() == b.getPrec() )
            return 0;
        else if( a.getPrec() < b.getPrec() )
            return -1;
        else
            return 1;
    }

    public opType getVal() { return val; }

    public Operator( opType v ) { val = v; }

}

回答1:


If you put a return, then the function returns before the break is executed and therefore the break will never be reached.

Instead you could use a variable that you set to a desired value and after the switch return that. Or just get rid of the break statements.




回答2:


you already have return which will make the break unreachable




回答3:


The reason that the code is unreachable is due to the return behaving like a break in that context - they both complete abruptly.

If a statement completes abruptly, then execution at that line is immediately returned to its appropriate context; if it's a break, it'll attempt to either exit the switch or return to its associated label if one exists; if it's a return, it will return to its caller, with or without a value.

This is why the code is unreachable: the line of code after the return can not be reached.

To really understand what that means or entails, we have to look at the Java Language Specification, specifically 14.1:

Every statement has a normal mode of execution in which certain computational steps are carried out. The following sections describe the normal mode of execution for each kind of statement.

If all the steps are carried out as described, with no indication of abrupt completion, the statement is said to complete normally. However, certain events may prevent a statement from completing normally:

The break (§14.15), continue (§14.16), and return (§14.17) statements cause a transfer of control that may prevent normal completion of statements that contain them.

Evaluation of certain expressions may throw exceptions from the Java Virtual Machine (§15.6). An explicit throw (§14.18) statement also results in an exception. An exception causes a transfer of control that may prevent normal completion of statements.

If such an event occurs, then execution of one or more statements may be terminated before all steps of their normal mode of execution have completed; such statements are said to complete abruptly.

An abrupt completion always has an associated reason, which is one of the following:

  • A break with no label

  • A break with a given label

  • A continue with no label

  • A continue with a given label

  • A return with no value

  • A return with a given value

  • A throw with a given value, including exceptions thrown by the Java Virtual Machine

The terms "complete normally" and "complete abruptly" also apply to the evaluation of expressions (§15.6). The only reason an expression can complete abruptly is that an exception is thrown, because of either a throw with a given value (§14.18) or a run-time exception or error (§11, §15.6).

If a statement evaluates an expression, abrupt completion of the expression always causes the immediate abrupt completion of the statement, with the same reason. All succeeding steps in the normal mode of execution are not performed.

Unless otherwise specified in this chapter, abrupt completion of a substatement causes the immediate abrupt completion of the statement itself, with the same reason, and all succeeding steps in the normal mode of execution of the statement are not performed.

Unless otherwise specified, a statement completes normally if all expressions it evaluates and all substatements it executes complete normally.




回答4:


The return statement effectively exits the method immediately. Since you've placed return statements inside the switch block for each case, whichever case is matched will, according to your code, return whatever value is indicated immediately. The break therefore cannot be executed, hence the error. You have two options:

1- Set a value, and return at the end of the method:

protected int getPrec(){
    int prec = 0;
    switch(val.getName()) {
        case "LParen": 
            prec = 0;
            break;
        case "RParen": 
            prec = 0;
            break;
        case "Mult":
            prec = 1;
            break;
        case "Div": 
            prec = 1;
            break;
        case "Mod": 
            prec = 1;
            break;
        case "Add": 
            prec = 2;
            break;
        case "Sub": 
            prec = 2;
            break;
        default:
            prec = 0;
            break; // technically unnecessary since we're at the end already but adding for completeness.
    }
        return prec;
}

2- Ditch the break; statements and keep the return statements as you've written them.

Personally I would prefer the first option as its cleaner and more readable to me. Plus it makes it easier to expand whatever actions need to be done in one or more cases if need be in the future.

By the way, watch your naming convention. You presently have:

public final class opType // bad naming

Since this is a class, the Java standard is to capitalize the first letter of the class. So it should be:

public final class OpType // good naming


来源:https://stackoverflow.com/questions/20157175/unreachable-statement-with-break

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!