我有一个简单的应用程序,允许用户输入除数,除数,然后计算商。 我使用vaadin作为框架,但我不认为这很重要。 所以我一直在考虑可能发生的异常,这些是我已经确定的: -Division by 0:ArithmeticException; - 用户输入字符串而不是数字:InputMismatchException 以下是创建表单并处理异常的类:
package my.vaadin.project.exceptionTest;
import java.awt.Component;
import java.util.InputMismatchException;
import com.vaadin.server.Page;
import com.vaadin.shared.Position;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Notification;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.event.Action;
public class Calculation extends CustomComponent{
final VerticalLayout vl = new VerticalLayout();
final TextField dividend = new TextField();
final TextField divisor = new TextField();
final TextField result = new TextField();
final Button resetButton = new Button("Reset");
private int divisionResult = 0;
Button button = new Button("Click Me");
public Calculation(){
dividend.setCaption("Enter the dividend:");
divisor.setCaption("Enter the divisor:");
result.setCaption("Result");
result.setReadOnly(true);
button.addClickListener( new Button.ClickListener(){
@Override
public void buttonClick(ClickEvent event) {
System.out.println("this is a test");
validateInputs();
}
});
resetButton.addClickListener(new Button.ClickListener(){
@Override
public void buttonClick(ClickEvent event) {
setDividend("");
setDivisor("");
setResult("");
}
});
vl.setMargin(true);
vl.setSpacing(true);
vl.addComponents(dividend, divisor, button, result );
}//end of constructor
public void validateInputs(){
System.out.println("theDivisor is " + getDivisor() + " theDividend " + getDividend());
try{
divisionResult = ( Integer.parseInt(getDividend()) / Integer.parseInt(getDivisor()));
}
catch(ArithmeticException arithmeticException){
System.err.println("Zero is an invalid denominator!");
createError("Divisor can't be 0!! Please enter a number > 0!");
}
catch(InputMismatchException inputMismatchException){
System.err.println("The dividend or divisor are not a number! Please enter a valid number!");
createError("The dividend or divisor are not a number! Please enter a valid number!");
}
}//end of validateInputs
public String getDivisor(){
return divisor.getValue();
}
public String getDividend(){
return dividend.getValue();
}
public void setDivisor(String newDivisor){
divisor.setValue(newDivisor);
}
public void setDividend(String newDividend){
dividend.setValue(newDividend);
}
public void setResult(String newResult){
result.setValue(newResult);
}
public void createError(String errorString){
String error = errorString;
Notification notif = new Notification(
error,
Notification.TYPE_ERROR_MESSAGE
);
notif.setDelayMsec(20000);
notif.show(Page.getCurrent());
}
}
我在计算商数时使用try catch语句(但我还没有显示结果)
如果我在除数中输入0,那么我得到了我所期望的,抛出并处理了ArithmeticException。 但是,如果我在字段中键入一个字符串,我会认为InputMismatchException会处理它,但实际上这是我在控制台http://pastebin.com/z8U6bUYg中得到的消息 我查看了NumberFormatException并且我不确定我知道该怎么做以及为什么会这样。正如您从代码中看到的那样,我将字符串解析为整数,但似乎编译器并不喜欢它。我是否必须添加一个catch语句并处理NumberFormatException?难道InputMismatchException不足够吗? 请让我知道你的想法
答案 0 :(得分:1)
如果查看Integer.parseInt
的文档,请指定:
抛出:
NumberFormatException
- 如果字符串不包含可解析的整数。
相反,InputMismatchException
文档指定了这个:
由
Scanner
抛出,表示检索到的令牌与预期类型的模式不匹配,或者令牌超出预期类型的范围。
因此,程序似乎表现正确并且符合规范。
这意味着您应该抓住NumberFormatException
而不是InputMismatchException
。
答案 1 :(得分:0)
不兼容问题
我在Android Studio 0.8.7上遇到同样的问题。但它适用于Android Studio 2.1。我认为应该通过将Android Studio和Gradle Plugin更新到最新版本来解决。
祝你好运答案 2 :(得分:-2)
极少数情况下你会抓住RuntimeException
。特别是在您的业务代码中,这是一个糟糕的模式。
确保在处理 之前验证输入值。您知道除数不能为零,因此,在您的示例中,您应该拒绝GUI中除数的输入为零,无论它是什么(HTML输入表单,Swing TextField等)。
最迟,您的二传手setDivisor()
不得接受0
并自行抛出异常,例如IllegalArgumentException。
此外,您应该将代码的问题分开。不要将数字计算与GUI混合使用。计算应该在另一个不了解GUI的类中进行。
PS /编辑:
试图解释为什么捕捉RuntimeException
并不是一个好主意:
摘自Oracle Docs:http://docs.oracle.com/javase/tutorial/essential/exceptions/catchOrDeclare.html
第三种异常是运行时异常。这些是 应用程序内部的特殊条件,以及 应用程序通常无法预期或从中恢复。这些 通常表示编程错误....
在您的情况下,应用程序可以预测并从用户输入无效除数的事实中恢复。更重要的是,您应该尽量避免让用户输入无效数据。
此外,关于SO的一些其他问题,人们同意捕获RuntimeExceptions是code smell
的事实。
是的,捕获任何RuntimeException几乎总是代码味道。该 C2 Wiki似乎同意。 Is Catching a Null Pointer Exception a Code Smell?
来自更官方消息来源的另一个
未经检查的异常:RuntimeException也从Exception扩展。 但是,从RuntimeException继承的所有异常都会获得 特别待遇。客户端代码无需处理 与他们,因此他们被称为未经检查的例外。 http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=1
它一直在继续......
同样,程序不能捕获RuntimeException,Exception或 抛出。很少(如果有的话)方法能够处理所有可能的方法 运行时异常。 https://www.securecoding.cert.org/confluence/display/java/ERR08-J.+Do+not+catch+NullPointerException+or+any+of+its+ancestors