在正确的时间抛出异常

时间:2011-05-17 22:42:12

标签: java exception exception-handling error-handling

刚刚遇到一个相当令人困惑的考试问题,我的讲师不在假期,所以我来StackOverflow寻求帮助!

问题如下:

“Joe有自己的JoeConnection类,用于在他的计算机和其他计算机之间建立连接。该类提供了以下构造函数和实例方法:

JoeConnection( String address ): Make a connection with the URL address.
void writeLn( String text ) : Write text to the JoeConnection.
String readLn( ): Read a line of text from the JoeConnection.
void clode( ) : Close the JoeConnection.

Joe的连接经常失败,这会导致错误。使用适当的异常处理,演示如何使用Joe的JoeConnection类

  1. 使用网址http://students.chat.box
  2. 制作JoeConnection
  3. 将“Hello world”写入JoeConnection
  4. 从JoeConnection
  5. 读取一个字符串
  6. 关闭连接。
  7. 连接处理应提供尽可能详细的故障原因,并打印导致故障的堆栈跟踪。

    我不知道如何解决这个问题,但我认为它与此类似:

    public class Test {
        try { 
            JoeConnection connection = new JoeConnection(http://students.chat.box); 
        } catch {
            connectionError e; printStacktrace();}
        }
    }
    

    任何人都可以帮我解决这个问题吗?非常感谢。

5 个答案:

答案 0 :(得分:3)

没有指示抛出了什么异常以及为什么,唯一正确的异常处理是 no 处理一点都不如果您不知道如何解决触发它的问题,请不要捕获异常。

但是你的作业中的进一步说明引入了一个不同的“正确”概念。你应该打印堆栈跟踪。因此捕获异常并打印堆栈跟踪。你走在正确的轨道上,但你的语法错了。请参阅您的教科书和讲义,以提醒自己捕获异常的语法是什么(以及将字符串传递给函数)。

try {
  JoeConnection connection = new JoeConnection("http://students.chat.box");
  connection.writeLn("Hello world");
  // etc
} catch (Exception e) {
  e.printStackTrace();
}

答案 1 :(得分:1)

“正确的异常处理”有点模糊。我同意@Rob Kennedy的声明,除非你知道抛出异常的原因以及应该如何处理它,否则不应该进行异常处理。否则,应该允许异常传播。所以,例如:

void foo(String address) throws JoeException {
    JoeConnection connection = new JoeConnection(address);
    try {
        connection.writeLn("Hello World!");
    } finally {
        // Ensure the connection is closed when finished.
        // This happens whether an exception occurs or not.
        connection.close();
    }
}

如果您想要捕获异常只是为了打印它,您可以这样做:

void foo(String address) throws JoeException {
    try {
        JoeConnection connection = new JoeConnection(address);
        try {
            connection.writeLn("Hello World!");
        } finally {
            connection.close();
        }
    } catch (JoeException e) {
        e.printStackTrace();
        // Don't know what to do about this; rethrow.
        throw e;
    }
}

这里有一个微妙之处,即使体验Java程序员也会错过。如果在创建连接时发生异常,则不需要关闭它。如果在写入连接时发生异常,则需要关闭 ;因此finally条款。但是,关闭行为也可以抛出异常。如果关闭连接会引发异常, try语句将仅抛出该异常。如果由于finally操作抛出异常而导致达到writeLn子句,则writeLn调用的例外将被有效忽略。这可能不是你想要的。

相反,我们可以尝试这样丑陋的东西:

void foo(String address) throws JoeException {
    try {
        JoeConnection connection = new JoeConnection(address);
        boolean normalCompletion = false;
        try {
            connection.writeLn("Hello World!");
            normalCompletion = true;
        } finally {
            if (normalCompletion) {
                // The writeLn operation completed normally.
                // Propagate an exception thrown by the close operation.
                connection.close();
            } else {
                // The writeLn operation completed abruptly.
                // Ignore an exception thrown by the close operation.
                try {
                    connection.close();
                } catch (JoeException e) {
                    /* empty */
                }
            }
        }
    } catch (JoeException e) {
        e.printStackTrace();
        // Don't know what to do about this; rethrow.
        throw e;
    }
}

这看起来(并且是)语法上可怕,但它确实显示了排序的“正确”异常处理。来自Project Coin的语言增强应该清理一下。

答案 2 :(得分:0)

对于初学者,我可以帮助你解决你所写的语法:

try {
    JoeConnection connection = new JoeConnection("http://students.chat.box");
}
catch (JoeConnectionException e) {
    e.printStacktrace();
}

我冒昧地改变了换行符并将'connectionError'重命名为JoeConnectionException,这对我来说更为传统。

你必须为readLn,writeLn和close方法调用做类似的事情,因为它说连接经常失败(即不仅仅是在连接时)。

欢呼,祝你好运。

答案 3 :(得分:0)

最好还有一个finally

public class Test {

    try { 
        JoeConnection connection = new JoeConnection(http://students.chat.box); 
    } 

    catch(Exception e) {
        e.printStacktrace();
    }

    finally {
       if(connection != null) {
          connection.close();
       }
    }
}

通常,如果您知道如何处理异常,则会处理异常(这涉及错误恢复逻辑或包装异常并将其抛出到更高级别)。

假设每个方法都抛出异常,你可以为“最大细节”执行类似的操作:

public class Test {

    JoeConnection connection = null;

    try {
       connection = new JoeConnection("http://students.chat.box");  
       ...
       ...           
    } 

    catch(OpenException e) {
       System.out.println("Error while opening connection");
       e.printStacktrace();
    }    

    catch(WriteException e) {
       System.out.println("Error while writing to connection");
       e.printStacktrace();
    }

    catch(ReadException e) {
       System.out.println("Error while reading from connection");
       e.printStacktrace();
    }

    finally {
       if(connection != null) {
          connection.close();
       }
    }
}

答案 4 :(得分:0)

捕获异常应如下所示:

try {
    JoeConnection conn = new JoeConnection(url);
} catch (YourExceptionClassNameHere e) {
    e.printStackTrace();
}

另外:如果要使用文字字符串,请确保包含引号。 (它应该是“http://students.chat.box”。)