在Java中,如果发生异常,如何设置返回类型?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2945545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Java, how do I set a return type if an exception occurs?
提问by James
hey all, I'm new to Java and was wondering if I define a method to return a database object
大家好,我是 Java 新手,想知道我是否定义了一个方法来返回数据库对象
like
喜欢
import java.sql.*;
public class DbConn {
public Connection getConn() {
Connection conn;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
if(System.getenv("MY_ENVIRONMENT") == "development") {
String hostname = "localhost";
String username = "root";
String password = "root";
}
conn = DriverManager.getConnection("jdbc:mysql:///mydb", username, password);
return conn;
} catch(Exception e) {
throw new Exception(e.getMessage());
}
}
}
if the connection fails when I try to create it what should I return? eclipse is telling me I have to return a Connection object but if it fails I'm not sure what to do.
如果在我尝试创建时连接失败,我应该返回什么?eclipse 告诉我我必须返回一个 Connection 对象,但如果它失败了,我不知道该怎么做。
thanks!
谢谢!
UPDATED CODE TO LET EXCEPTION BUBBLE:
更新代码以让例外冒泡:
public class DbConn {
public Connection getConn() throws SQLException {
Connection conn;
String hostname = "localhost";
String username = "root";
String password = "root";
Class.forName("com.mysql.jdbc.Driver").newInstance();
if(System.getenv("MY_ENVIRONMENT") != "development") {
hostname = "localhost";
username = "produser";
password = "prodpass";
}
conn = DriverManager.getConnection("jdbc:mysql:///mydb", username, password);
return conn;
}
}
采纳答案by Péter T?r?k
If an exception is thrown, there is no normal value returned from the method. Usually the compiler is able to detect this, so it does not even pester you with "return required" style warnings/errors. Sometimes, when it is not able to do so, you need to give an "alibi" return statement, which will in fact never get executed.
如果抛出异常,则该方法没有返回正常值。通常编译器能够检测到这一点,所以它甚至不会用“需要返回”样式的警告/错误来纠缠你。有时,当它不能这样做时,你需要给出一个“不在场证明”的返回语句,它实际上永远不会被执行。
Redefining your method like this
像这样重新定义你的方法
public Connection getConn() {
Connection conn = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
if(System.getenv("MY_ENVIRONMENT") == "development") {
String hostname = "localhost";
String username = "root";
String password = "root";
}
conn = DriverManager.getConnection("jdbc:mysql:///mydb", username, password);
} catch(Exception e) {
// handle the exception in a meaningful way - do not just rethrow it!
}
return conn;
}
will satisfy Eclipse :-)
将满足 Eclipse :-)
Update:As others have pointed out, re-throwing an exception in a catch block the way you did is not a good idea. The only situation when it is a decent solution is if you need to convert between different exception types. E.g. a method called throws an exception type which you can not or do not want to propagate upwards (e.g. because it belongs to a proprietary library or framework and you want to isolate the rest of your code from it).
更新:正如其他人指出的那样,以您的方式在 catch 块中重新抛出异常并不是一个好主意。它是一个不错的解决方案的唯一情况是您是否需要在不同的异常类型之间进行转换。例如,一个称为抛出异常类型的方法,您不能或不想向上传播(例如,因为它属于专有库或框架,并且您希望将其余代码与其隔离)。
Even then, the proper way to rethrow an exception is to pass the original exception into the new one's constructor (standard Java exceptions and most framework specific exceptions allow this). This way the stack trace and any other information within the original exception is retained. It is also a good idea to log the error before rethrowing. E.g.
即便如此,重新抛出异常的正确方法是将原始异常传递到新的构造函数中(标准 Java 异常和大多数框架特定异常允许这样做)。这样,原始异常中的堆栈跟踪和任何其他信息都会被保留。在重新抛出之前记录错误也是一个好主意。例如
public void doSomething() throws MyException {
try {
// code which may throw HibernateException
} catch (HibernateException e) {
logger.log("Caught HibernateException", e);
throw new MyException("Caught HibernateException", e);
}
}
回答by Michael Borgwardt
This is exactly the situation where you should let the exception propagate up the call stack (declaring the method as throws SQLException
or wrapping it in a application-specific exception) so that you can catch and handle it at a higher level.
在这种情况下,您应该让异常沿调用堆栈向上传播(将方法声明为throws SQLException
或将其包装在特定于应用程序的异常中),以便您可以在更高级别捕获和处理它。
That's the whole point of exceptions: you can choose where to catch them.
这就是异常的全部意义:您可以选择在哪里捕获它们。
回答by JSB????
You should just eliminate your entire try/catch
block and allow exceptions to propagate, with an appropriate exception declaration. This will eliminate the error that Eclipse is reporting, plus right now your code is doing something very bad: by catching and re-throwing all exceptions, you're destroying the original stack trace and hiding other information contained in the original exception object.
您应该try/catch
使用适当的异常声明消除整个块并允许异常传播。这将消除 Eclipse 报告的错误,而且现在您的代码正在做一些非常糟糕的事情:通过捕获和重新抛出所有异常,您正在破坏原始堆栈跟踪并隐藏原始异常对象中包含的其他信息。
Plus, what is the purpose of the line Class.forName("com.mysql.jdbc.Driver").newInstance();
? You're creating a new mysql Driver
object through reflection (why?) but you're not doing anything with it (why?).
另外,这条线的目的是Class.forName("com.mysql.jdbc.Driver").newInstance();
什么?您正在Driver
通过反射创建一个新的 mysql对象(为什么?),但您没有对它做任何事情(为什么?)。
回答by Paul Tomblin
Never, ever, ever use a generic exception like that. If you don't have a ready made exception (in this case, an SQLException), make your own exception type and throw it. Every time I encounter something that declares that it "throws Exception", and it turns out that it does so because something it calls declares "throws Exception", and so on down the line, I want to strangle the idiot who started that chain of declarations.
永远,永远,永远不要使用这样的通用异常。如果您没有现成的异常(在本例中为 SQLException),请创建您自己的异常类型并抛出它。每次我遇到一些声明它“抛出异常”的东西,事实证明它这样做是因为它调用的东西声明“抛出异常”,等等,我想扼杀那个开始那条链的白痴声明。
回答by duffymo
I'm sorry, but you shouldn't be writing code like this, even if you're new to Java.
抱歉,您不应该编写这样的代码,即使您是 Java 新手。
If you must write such a thing, I'd make it more like this:
如果你一定要写这样的东西,我会让它更像这样:
public class DatabaseUtils
{
public static Connection getConnection(String driver, String url, String username, String password) throws SQLException
{
Class.forName(driver).newInstance();
return DriverManager.getConnection(url, username, password);
}
}
And you should also be aware that connection pools are the true way to go for anything other than a simple, single threaded application.
而且您还应该意识到,连接池是除简单的单线程应用程序之外的任何其他应用程序的真正方式。
回答by Sunil Kumar Sahu
Try this one
试试这个
public ActionForward Login(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
MigForm migForm = (MigForm) form;// TODO Auto-generated method stub
Connection con = null;
Statement st = null;
ResultSet rs = null;
String uname=migForm.getUname();
String pwd=migForm.getPwd();
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:XE","uname","pwd");
if(con.isClosed())
{
return mapping.findForward("success");
}
//st=con.createStatement();
}catch(Exception err){
System.out.println(err.getMessage());
}
return mapping.findForward("failure");
}