具有中断的无法访问的声明

所以我有一个上一个问题,但意识到我发布了错误的违规代码。 我在下面标出了令人不快的陈述。

我想要做的是为每个具有该switch语句的运算符设置优先级。

也许有人可以指出我正确的方向。

就像一张纸条,我正在运行JAVA 7,因此String Switch可以工作。

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; } } 

如果你输入一个return ,那么函数会在执行break之前返回,因此永远不会达到break

相反,您可以使用您设置为所需值的变量,并在交换机返回之后。 或者只是摆脱break声明。

你已经有了return ,这将使break无法到达

代码无法访问的原因是由于return在该上下文中表现得像一个break – 它们都突然完成。

如果一个语句突然完成,那么该行的执行会立即返回到其适当的上下文; 如果它是一个break ,它将尝试退出switch或返回其相关标签(如果存在); 如果它是一个return ,它将返回其调用者,有或没有值。

这就是代码无法访问的原因:无法访问return后的代码行。

要真正理解这意味着什么或需要什么,我们必须查看Java语言规范,特别是14.1 :

每个语句都有一个正常的执行模式,其中执行某些计算步骤。 以下部分描述了每种语句的正常执行模式。

如果所有步骤都按照描述执行,没有突然完成的指示,则说该语句正常完成。 但是,某些事件可能会阻止语句正常完成:

中断(§14.15),continue(§14.16)和return(§14.17)语句导致控制转移,这可能会阻止包含它们的语句的正常完成。

对某些表达式的评估可能会从Java虚拟机(第15.6节)中抛出exception。 显式throw(第14.18节)语句也会导致exception。 exception会导致控制权转移,从而可能导致语句无法正常完成。

如果发生这样的事件,则可以在其正常执行模式的所有步骤完成之前终止一个或多个语句的执行; 据说这些陈述突然完成。

突然完成总是有一个相关的原因,这是下列之一:

  • 没有标签的break

  • 与给定标签的break

  • continue没有标签

  • continue使用给定的标签

  • 没有价值的return

  • 具有给定值的return

  • 具有给定值的throw ,包括Java虚拟机抛出的exception

术语“正常完成”和“突然完成”也适用于表达式的评估(第15.6节)。 表达式突然完成的唯一原因是抛出exception,因为抛出给定值(第14.18节)或运行时exception或错误(第11节,第15.6节)。

如果语句计算表达式,表达式的突然完成总会导致语句的立即突然完成,原因相同。 不执行正常执行模式中的所有后续步骤。

除非本章另有规定,否则突然完成子语句会导致语句本身立即突然完成,原因相同,并且不执行语句正常执行模式中的所有后续步骤。

除非另有说明,否则如果所有表达式都已计算并且所有执行的子语句正常完成,则语句将正常完成。

return语句有效地立即退出该方法。 由于您已经为每种caseswitch块中放置了return语句,因此根据您的代码,无论哪种case匹配,都会返回任何立即指示的值。 因此不能执行break ,因此错误。 你有两个选择:

1-设置一个值,并在方法结束时返回:

 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-抛弃break; 语句并在您编写它们时保留return语句。

就个人而言,我更喜欢第一个选项,因为它更清洁,更易读。 此外,如果将来需要,还可以更容易地扩展在一个或多个案例中需要执行的任何操作。

顺便说一句,看看你的命名惯例。 你现在有:

 public final class opType // bad naming 

由于这是一个类,Java标准是大写该类的第一个字母。 所以它应该是:

 public final class OpType // good naming