Java - 必须抛出异常,但是如何抛出?

3

我在NetBeans中遇到了一个错误,它说我必须在这个方法中抛出SQLException:

private void displayCustomerInfo(java.awt.event.ActionEvent evt)                                     
{                                         
    int custID = Integer.parseInt(customerID.getText());
    String info = getCustomerInfo(custID);
    results.setText(info);
}

这个方法是由NetBeans创建的,所以我不能编辑签名和抛出异常。这就是为什么我创建了getCustomerInfo()方法。该方法会抛出异常,因为它使用一个从数据库中检索客户信息的方法。

public String getCustomerInfo(int cid) throws SQLException
{
    Customer c = proc.getCustomer(cid);
    // get info
    return "info";
}
getCustomer方法也会抛出异常,而且proc.java可以编译通过。
具体错误信息为:
unreported exception java.sql.SQLException; must be caught or declared to be thrown

请原谅我,但为什么大家只谈论try-catch?这是一种选择,但不是唯一的选择。为什么不能抛出异常?为什么Netbeans不允许呢?虽然我不使用Netbeans(而是使用Eclipse),但听起来很荒谬,一个集成开发环境不允许更改生成的代码。 - Nivas
6个回答

10

通常情况下,如果你的代码需要抛出一个接口不支持的异常类型,并且你无法控制该接口,你可以捕获并重新抛出一个接口支持的类型。如果你的接口没有声明任何受检异常,那么你总是可以抛出一个RuntimeException:

private void displayCustomerInfo(java.awt.event.ActionEven evt)                                     
{        
    try
    {                                 
        int custID = Integer.parseInt(customerID.getText());
        String info = getCustomerInfo(custID);
        results.setText(info);  
    }
    catch (SQLException ex)
    {
        throw new RuntimeException(ex);  // maybe create a new exception type?
    }
}

你几乎肯定想创建一个扩展RuntimeException的新异常类型,并让客户端代码捕获该异常。否则,你会冒着捕获任何RuntimeException(包括NullPointerException、ArrayIndexOutOfBoundsException等)的风险,而这些异常客户端代码可能无法处理。


我会给你一个+1,因为你提供了一个正确的答案解决了问题,而且很可能是OP必须要做的,但您能否请注意一下,在RuntimeExceptions中隐藏东西通常被视为不良实践? :D - rmeador
这被一些人认为是一种不好的做法。在许多情况下,将一个本应该不在Java语言中的已检查异常转换成未检查异常是一件好事。Hibernate 在所有情况下都是这样做的,例如。 - jsight
我已经编辑了答案,以更清晰地解释问题。我对RuntimeExceptions没有问题,但我认为最好还是创建一个新类型,这样客户端至少可以知道调用失败的原因。 - Tim Frey
在这种情况下,处理它几乎肯定更好:使用setText()编写错误消息。 - DJClayworth

8

请再次阅读错误信息,它给出了两个选择。

你必须要么声明抛出异常(这是不可能的),要么捕获异常。尝试第二种选择。


3
您需要在调用getCustomerInfo()的代码块周围放置一个try/catch块,如下所示:
private void displayCustomerInfo(java.awt.event.ActionEvent evt)                                     
{                                         
    int custID = Integer.parseInt(customerID.getText());
    try {
        String info = getCustomerInfo(custID);
    } catch (SQLException sqle) {
        // Do something with the exception
    }

    results.setText(info);
}

处理异常的几个好方法可能是:记录异常及其获取细节,或将其作为重试连接请求的信号。另外,正如Outlaw程序员所示,您可以将异常重新抛出为某种RuntimeException,这样就不需要检查了。


2

它并未说您必须将其抛出。而是说您可以捕获它。因此,请使用try/catch块并处理它。

try {
    ...
}
catch (SQLException e) {
    System.out.println("Exception happened! Abort! Abort!");
    e.printMessage(); //Not sure if this is the correct method name
}

1
NetBeans生成的组件具有不可修改的代码,我猜测这是作为GUI构建器的一部分生成的。我想问一下是否是这种情况,但我还不能发表评论。如果您在GUI编辑器中选择一个生成的对象,在右侧会出现一个名为“代码”的选项卡,可以用来修改代码的灰色区域。
这里是:
Code tab that is used to modify generated code.

0
我遇到了这个问题...已经困惑了两天...然后我用Sublime打开源代码(.java文件),修改了代码,保存后,它奇迹般地工作了...当我看到这个工作时,我笑了...真正的创新思维起到了作用...

1
你在源文件中做了什么修改?请说明修改内容,这将有助于其他人。 - Prasoon Karunan V

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接