NumberFormatException:如何处理它

时间:2016-07-10 21:55:39

标签: java vaadin vaadin7 numberformatexception

我有一个简单的应用程序,允许用户输入除数,除数,然后计算商。 我使用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不足够吗? 请让我知道你的想法

3 个答案:

答案 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