2010-05-31 3 views
8

hey alle, ich bin neu zu Java und mich gefragt, ob ich eine Methode zurückzukehren, um ein DatenbankobjektIn Java, wie setze ich einen Rückgabetyp, wenn eine Ausnahme auftritt?

wie

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()); 
     } 

    } 

} 

wenn die Verbindung fehlschlägt definieren, wenn ich versuche, es zu schaffen, was soll ich zurückkehren ? Eclipse sagt mir, dass ich ein Connection-Objekt zurückgeben muss, aber wenn es fehlschlägt, bin ich mir nicht sicher, was ich tun soll.

danke!

AKTUALISIERT CODE AUSNAHME BUBBLE zu vermieten:

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; 

    } 

} 
+0

Ehrlich gesagt, ich bin erstaunt. Eclipse ist normalerweise intelligent genug, um zu verstehen, dass Sie nichts zurückgeben müssen, wenn Sie einmal etwas geworfen haben. Aber um es glücklich zu machen, setze ein "Return null"; nach dem Ende des Fangblocks. –

+0

@Paul: eigentlich ist Eclipse nur unglücklich über "Unhandled Exception Typ Ausnahme" innerhalb der Catch (fehlende Würfe). –

Antwort

5

Wenn eine Ausnahme ausgelöst wird, gibt es kein Normalwert aus dem Verfahren zurückgeführt. Normalerweise ist der Compiler in der Lage, dies zu erkennen, so dass Sie nicht einmal mit Warnmeldungen/Fehlern vom Typ "return required" belästigt werden. Manchmal, wenn dies nicht möglich ist, müssen Sie eine "Alibi" -Rückkehranweisung geben, die tatsächlich niemals ausgeführt wird.

Neudefinition Ihre Methode wie folgt

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; 
} 

wird Eclipse-befriedigen :-)

Update: Wie andere haben darauf hingewiesen, Wieder Auslösen einer Ausnahme in einem catch-Block, wie Sie ist getan keine gute Idee. Die einzige Situation, wenn es eine anständige Lösung ist, ist, wenn Sie zwischen verschiedenen Arten von Ausnahmen konvertieren müssen. Z.B. Eine Methode mit dem Namen throws gibt einen Ausnahmetyp aus, den Sie nicht weitergeben können oder wollen (z. B. weil er zu einer proprietären Bibliothek oder einem Framework gehört und Sie den Rest Ihres Codes davon isolieren möchten).

Auch dann besteht die richtige Methode zum Auslösen einer Ausnahme darin, die ursprüngliche Ausnahme in den neuen Konstruktor zu übernehmen (standardmäßige Java-Ausnahmen und die meisten rahmenspezifischen Ausnahmen erlauben dies). Auf diese Weise werden die Stapelverfolgung und alle anderen Informationen innerhalb der ursprünglichen Ausnahme beibehalten. Es ist auch eine gute Idee, den Fehler vor dem erneuten Einlesen zu protokollieren. Z.B.

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); 
    } 
} 
+0

Eclipse sagt, dass diese Methode einen Collection-Typ zurückgeben muss und ein Fehlersymbol in der Zeile mit der Methode delcaration aufweist. – James

+1

@beagleguy das ist, weil es einen Code-Pfad gibt, der nicht zu einer Rückkehr oder einem Wurf führt. Der von Ihnen gepostete Code ist jedoch anscheinend nicht vollständig, da er keinen solchen Codepfad enthält. – Yishai

+0

danke Peter, ich habe meinen Code aktualisiert, um den Versuch/Fang zu entfernen .. 2. Version besser aussehen? – James

1

Dies ist genau die Situation, in der Sie die Ausnahme den Call-Stack propagieren bis lassen sollen (die Methode als throws SQLException erklärt oder es in einer anwendungsspezifischen Ausnahme Einwickeln), so dass Sie es mit einem höheren abfangen und behandeln Niveau.

Das ist der springende Punkt von Ausnahmen: Sie können wählen, wo Sie sie fangen.

5

Sie sollten nur Ihren gesamten try/catch Block beseitigen und zulassen, dass Ausnahmen propagiert werden, mit einer entsprechenden Ausnahmedeklaration. Dadurch wird der Fehler behoben, den Eclipse gemeldet hat, und genau jetzt macht Ihr Code etwas sehr Schlechtes: Indem Sie alle Ausnahmen abfangen und erneut werfen, zerstören Sie den ursprünglichen Stack-Trace und verstecken andere Informationen, die im ursprünglichen Ausnahmeobjekt enthalten sind.

Plus, was ist der Zweck der Linie Class.forName("com.mysql.jdbc.Driver").newInstance();? Sie erstellen ein neues mysql Driver Objekt durch Reflektion (warum?), Aber Sie tun nichts damit (warum?).

+0

Wenn ich diese Zeile nicht habe, bekomme ich die Ausnahme: Allgemeine Ausnahme: Kein geeigneter Treiber für jdbc gefunden: mysql: /// meinedb gibt es eine bessere Möglichkeit, ein mysql-Verbindungsobjekt zu bekommen? – James

+1

@beagleguy, ich sehe von Google, dass diese Methode der Erstellung tatsächlich empfohlen wird. Huh. Ich schätze, die Autoren von jdbc haben noch nie von Dependency Injection gehört. –

1

Niemals jemals eine generische Ausnahme wie diese verwenden. Wenn Sie keine vorbereitete Ausnahme (in diesem Fall eine SQLException) haben, erstellen Sie einen eigenen Ausnahmetyp und werfen Sie ihn.Jedes Mal, wenn ich auf etwas stoße, das erklärt, dass es "Exception" auslöst, und es sich herausstellt, dass es "Exceptions wirft" und so weiter, will ich den Idioten erwürgen, der diese Kette von gestartet hat Erklärungen.

0

Es tut mir leid, aber Sie sollten nicht Code wie diesen schreiben, auch wenn Sie neu in Java sind.

Wenn Sie so etwas schreiben muss, würde ich es eher wie dieses machen:

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); 
    } 
} 

Und Sie sollten sich auch bewusst sein, dass Verbindungspools der richtige Weg sind für alles andere als eine einfache gehen, Single-Thread-Anwendung.

0

Versuchen Sie dieses

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"); 



} 
Verwandte Themen