use*_*033 24 java exception-handling
我不得不用一些代码回答这个问题:
假设我编写了以下方法规范:
public void manipulateData ( ) throws java.sql.SQLException, java.sql.SQLDataException您正在编写将使用此方法的数据库程序的代码,并且您希望专门处理每个方法.try/catch子句应该是什么样的?
您可以使用no-ops-- empty blocks {} - 用于catch子句内容.
我们只对这里语句的语法和结构感兴趣.
我回答说:
try {
} catch(java.sql.SQLException e) {
}
catch(java.sql.SQLDataException e) {
}
Run Code Online (Sandbox Code Playgroud)
由于这个原因,他没有接受答案:
"你的捕获条款的顺序是错误的.你能解释为什么这个命令很重要吗?"
他的答案是否正确?
use*_*001 42
是的,他是对的.正如你在Javadoc中看到的那样,SQLDataException是一个子类SQLException.因此,您的答案是错误的,因为它会在第二个中创建一块无法访问的代码catch.
在Java中,此代码甚至不会编译.在其他语言(例如python)中,这样的代码会创建一个微妙的bug,因为SQLDataException实际上会在第一个块中捕获,而不是在第二个块中捕获(如果它不是子类的话就是这种情况).
如果你回答catch(java.sql.SQLException | java.sql.SQLDataException e) { },它仍然是不正确的,因为问题要求具体处理每个例外.
正确答案在Grijesh的回答中
Dig*_*ara 22
在Java中,您必须首先放置包含最少的Exception.接下来的例外必须更具包容性(当它们相关时).
例如:如果你把所有(最多)的包容性放在首位,那么永远不会调用下一个.像这样的代码:
try {
System.out.println("Trying to prove a point");
throw new java.sql.SqlDataException("Where will I show up?");
}catch(Exception e){
System.out.println("First catch");
} catch(java.sql.SQLException e) {
System.out.println("Second catch");
}
catch(java.sql.SQLDataException e) {
System.out.println("Third catch");
}
Run Code Online (Sandbox Code Playgroud)
永远不会打印您希望打印的信息.
由于以下原因,在捕获异常时订购事项:
记得:
e 是一个参考变量Run Code Online (Sandbox Code Playgroud)catch(ExceptionType e){ }
小写字符e是对抛出(和捕获)ExceptionType对象的引用.
您的代码未被接受的原因?
重要的是要记住异常子类必须在它们的超类之前.这是因为使用超类的catch语句将捕获该类型及其任何子类的异常.因此,如果它来自超类,则永远不会到达子类.
此外,在Java中,无法访问的代码是错误的.
SQLException 是超级类的 SQLDataException
+----+----+----+
| SQLException | `e` can reference SQLException as well as SQLDataException
+----+----+----+
^
|
|
+----+----+----+---+
| SQLDataException | More specific
+----+----+----+---+
Run Code Online (Sandbox Code Playgroud)
如果你的写作有错误 Unreachable code(阅读评论):
try{
}
catch(java.sql.SQLException e){//also catch exception of SQLDataException type
}
catch(java.sql.SQLDataException e){//hence this remains Unreachable code
}
Run Code Online (Sandbox Code Playgroud)
如果您尝试编译此程序,您将收到一条错误消息,指出第一个catch语句将处理所有基于SQLException的错误,包括SQLDataException.这意味着第二个catch语句永远不会执行.
正确的解决方案?
修复它反转catch语句的顺序.接下来是:
try{
}
catch(java.sql.SQLDataException e){
}catch(java.sql.SQLException e){
}
Run Code Online (Sandbox Code Playgroud)
SQLDataException永远不会被击中,因为它SQLException会在到达之前捕获任何SQL异常SQLDataException.
SQLDataException是一个子类的SQLException
想想异常的继承层次结构:SQLDataException extends SQLException所以如果你首先捕获'泛型'(即层次结构中最顶层的基类),那么由于多态性,每个"低于"的东西都属于同一类型,即SQLDataException isa SQLException
因此,你应该在继承层次结构中以自下而上的顺序捕获它们,即,子类首先一直到(泛型)基类.这是因为catch条款是按照您声明它们的顺序进行评估的.
| 归档时间: |
|
| 查看次数: |
10462 次 |
| 最近记录: |