将switch分支的return改为break后,赋值给resultValue的值未被使用?求助
首先咱们先捋清楚核心问题:你之前用return的时候,每个case赋值完resultValue就直接返回了,下面的result.setText(...)根本不会执行——也就是说你之前的代码其实根本不会显示计算结果!这才是隐藏的大问题,只是编译器没提示而已。
现在改成break之后,编译器弹出“赋值给resultValue的xxx值从未被使用”的提示,看起来有点矛盾,因为明明之后会用resultValue来设置文本。其实这大概率是静态代码分析工具(比如Android Studio的lint)的小误报,但咱们可以通过调整代码逻辑彻底解决这个提示,同时让代码更简洁合理:
方案一:直接在case分支中设置结果文本
既然最终目的是把计算结果显示到result上,完全不需要resultValue这个中间变量,直接在每个case里计算并设置文本就好,代码更直观:
public void operationOnClick(View view){ int operandOneValue = Integer.valueOf(operandOne.getText().toString()); int operandTwoValue = Integer.valueOf(operandTwo.getText().toString()); Button op = (Button)view; String operation = op.getText().toString(); switch(operation){ case "+" : result.setText(String.valueOf(operandOneValue + operandTwoValue)); break; case "-" : result.setText(String.valueOf(operandOneValue - operandTwoValue)); break; case "*" : result.setText(String.valueOf(operandOneValue * operandTwoValue)); break; case "/" : result.setText(String.valueOf(operandOneValue / operandTwoValue)); break; default: // 处理未知操作符的情况,比如显示错误提示 result.setText("未知操作"); break; } }
方案二:保留resultValue但优化逻辑
如果你非要保留resultValue变量,可以去掉提前初始化,同时添加default分支,让编译器确认所有路径下resultValue都被正确赋值,这样就不会再提示了:
public void operationOnClick(View view){ int operandOneValue = Integer.valueOf(operandOne.getText().toString()); int operandTwoValue = Integer.valueOf(operandTwo.getText().toString()); int resultValue; // 不提前初始化,强制检查所有分支都赋值 Button op = (Button)view; String operation = op.getText().toString(); switch(operation){ case "+" : resultValue = operandOneValue + operandTwoValue; break; case "-" : resultValue = operandOneValue - operandTwoValue; break; case "*" : resultValue = operandOneValue * operandTwoValue; break; case "/" : resultValue = operandOneValue / operandTwoValue; break; default: resultValue = 0; // 或者设置错误码/提示文本对应的数值 break; } result.setText(String.valueOf(resultValue)); }
为什么会出现这个提示?
原来的代码里,你提前把resultValue初始化为0,静态分析工具可能会钻牛角尖:如果operation匹配某个case,你赋值了新的resultValue,但会不会被后续代码覆盖?(当然不会,但工具的判断逻辑有时候比较刻板)。而去掉提前初始化+添加default分支后,编译器能确认所有路径下resultValue都被赋值,且之后会被setText使用,自然就不会再提示了。
另外再强调一句:之前用return的代码逻辑是错误的,因为计算完结果后根本不会显示出来,改成break才是正确的方向,只是这个提示有点误导人而已。
内容的提问来源于stack exchange,提问作者Henok Tesfaye

