0

私はこのクラスをさまざまなポストから可能な限り上手に構築してきました。

MySQLデータベースからユーザー名のリストを取得しようとしています。

それらを取得する方法は次のとおりです。

public ArrayList<String> LoadUsers() throws SQLException {
    ArrayList<String> players = new ArrayList<String>();
    try {
        Connection conn = null;
        ResultSet rs = null;

        try {
            conn = getConnection();
            Statement s = conn.createStatement ();
            s.executeQuery ("SELECT * FROM NFT_users");
            rs = s.getResultSet ();

            while(rs.next ()){
                players.add(rs.getString("name"));
            }
            rs.close ();
            s.close ();
        }

        catch (SQLException ex) { 
            System.out.println(ex.toString()); 
        }

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

            catch (SQLException ex) { 
                System.out.println("On close: " + ex.toString()); 
            } 
        }
    } 

    catch(Exception ex) { 
        //trace(ex); 
    }

    return players;
}

そして、これはメソッドからそれを取得する私のメインクラスのコードです:

    ArrayList<String> players = database.LoadUsers();

ただし、エラーが発生します。キャッチするか、スローするように宣言する必要があります。私は何を間違えますか?

4

3 に答える 3

3

あなたの方法:-

public ArrayList<String> LoadUsers() throws SQLException {

SQLExceptionそのthrows節でを宣言しました。したがって、このメソッドを呼び出すメソッドのいずれからでも、この例外を処理するためにをブロックで囲むか、そのメソッドのthrows句でこの例外を宣言する必要がありinvocationますtry-catch

したがって、メソッドからメソッドを呼び出しているとしますcaller()

したがって、2つのオプションがあります。-

  1. throwsの節で例外を宣言しますcaller:-

    public void caller() throws SQLException {
         ArrayList<String> players = database.LoadUsers();
    }
    
  2. メソッド呼び出しをtry-catchで囲みます。この場合、list最初にブロックの外側を宣言することを忘れないでください。

    public void caller() {
         ArrayList<String> players = null;
         try {
              players = database.LoadUsers();
         } catch (SQLException e) {
              e.printStackTrace();
         }
    }
    

最初のオプションを使用している場合は、を呼び出したメソッドでも同じ問題が発生することに注意callerしてください。そこにもあなたはこのことに従う必要があるでしょう。

一般に、メソッド内で発生した例外は、try-catchブロックを使用してそこで処理されるか、スタックトレースを直接呼び出し元のメソッドに伝播されますが、両方は伝播されません。あなたはあなたの方法で両方をやっています。あなたは例外を処理していて、それもthrows句でスローされるように宣言しています。あなたは決してそれをすべきではありません。

于 2012-11-30T21:24:02.237 に答える
0

以前のコメントで述べたように、LoadUsersメソッドが例外をスローすることを宣言してから、決してスローしないことはお勧めできません。これにより、呼び出し元が例外を処理する準備ができている必要があります。実際、コンパイラーは、呼び出し元がtry / catchブロックで呼び出しを囲むか、例外をスローすることを宣言することを要求します。

したがって、(少なくとも)3つのオプションがあります。1つ目は、次のように、LoadUsersメソッドが実際に例外をスローするようにすることです。

public ArrayList<String> LoadUsers() throws SQLException {
    ArrayList<String> players = new ArrayList<String>();
    try {
        Connection conn = null;
        ResultSet rs = null;

        try {
            conn = getConnection();
            Statement s = conn.createStatement ();
            s.executeQuery ("SELECT * FROM NFT_users");
            rs = s.getResultSet ();

            while(rs.next ()){
                players.add(rs.getString("name"));
            }
            rs.close ();
            s.close ();
        } finally { 
            try { 
                if (conn != null) conn.close(); 
            } catch (SQLException ex) { 
                // eat the exception - we can't do anything about it here 
            } 
        }
    } 

    return players;
}

発信者の場合:

public void processPlayers() {
   try{
       ArrayList<String> players = database.LoadUsers();
      // do something with the players

   } catch(SQLException ex){

     ex.printStackTrace();
  }
}

2番目のオプションは同じLoadUsers()メソッドを使用しますが、呼び出し元でも例外をキャッチしません。呼び出し元に例外を渡します

public void processPlayers() throws SQLException {
      ArrayList<String> players = database.LoadUsers();
      // do something with the players
}

3番目のオプションは、呼び出し元ではなく、LoadUsersメソッドで例外をキャッチすることです。ここでの問題は、呼び出し元が問題が発生したことを認識しないことです。空のリストを取得するだけです。

public ArrayList<String> LoadUsers() throws SQLException {
    ArrayList<String> players = new ArrayList<String>();
    try {
        Connection conn = null;
        ResultSet rs = null;

        try {
            conn = getConnection();
            Statement s = conn.createStatement ();
            s.executeQuery ("SELECT * FROM NFT_users");
            rs = s.getResultSet ();

            while(rs.next ()){
                players.add(rs.getString("name"));
            }
            rs.close ();
            s.close ();
        } catch(SQLException ex) {
            ex.printStackTrace(); // but the caller won't know...
        }
          finally { 
            try { 
                if (conn != null) conn.close(); 
            } catch (SQLException ex) { 
                // eat the exception - we can't do anything about it here 
            } 
        }
    } 

    return players;
}

public void processPlayers() throws SQLException {
      ArrayList<String> players = database.LoadUsers(); // an empty list if something went wrong
      // do something with the players
}

この最後のオプションはお勧めしません。

于 2012-11-30T21:53:34.263 に答える
0

これを試して

try{
   ArrayList<String> players = database.LoadUsers();
}catch(SQLException e){e.printStackTrace();}

これは、loadUsersメソッドが例外をスローしているためです。したがって、このメソッドを呼び出す場合は常に、trycatchで囲む必要があります。

于 2012-11-30T21:27:00.837 に答える