Reputation: 303
I have built this class up from various post as good as i could.
I am trying to get a list of usernames from a MySQL database.
Here is the method retrieving them:
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;
}
And this is the code in my mainclass which retrieves it from the method:
ArrayList<String> players = database.LoadUsers();
However, i get the error Must be caught or declared to be thrown. What do i do wrong?
Upvotes: 0
Views: 588
Reputation: 30088
As I mentioned in a previous comment, it's not a good idea to declare that the LoadUsers method throws an exception, and then to never throw it. This raises the expectation that the caller should be prepared to handle the exception, and indeed, the compiler will demand that the caller either surround the call with a try/catch block, or declare that it throws the exception.
So, there are (at least) three options. The first is to have the LoadUsers method actually throw the exception, like this:
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;
}
and in the caller:
public void processPlayers() {
try{
ArrayList<String> players = database.LoadUsers();
// do something with the players
} catch(SQLException ex){
ex.printStackTrace();
}
}
The second option uses the same LoadUsers() method, but doesn't catch the exception in the caller either - it passes it on to its caller:
public void processPlayers() throws SQLException {
ArrayList<String> players = database.LoadUsers();
// do something with the players
}
The third option is to catch the exception in the LoadUsers method, and not in the caller. The problem here is that the caller won't know that there was problem - it will just get an empty list:
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;
}
and
public void processPlayers() throws SQLException {
ArrayList<String> players = database.LoadUsers(); // an empty list if something went wrong
// do something with the players
}
This last option is not recommended.
Upvotes: 0
Reputation: 213401
Your method: -
public ArrayList<String> LoadUsers() throws SQLException {
has declared an SQLException
in it's throws clause. So, from whichever method you call this method from, you would either need to enclose the invocation
in a try-catch
block to handle this exception, or declare this exception in the throws clause of that method also.
So, suppose you are calling your method from a method caller()
.
So, you have two options: -
Declare exception in throws
clause of caller
: -
public void caller() throws SQLException {
ArrayList<String> players = database.LoadUsers();
}
Enclose the method invocation in a try-catch. In this case, remember to declare your list
outside the block first:
public void caller() {
ArrayList<String> players = null;
try {
players = database.LoadUsers();
} catch (SQLException e) {
e.printStackTrace();
}
}
Note that, if you are using the first option, then you will again face same problem in the method that called caller
. There also you would have to follow this thing.
In general, an exception raised inside a method is - either handled there using try-catch block, or is propagated up the stack trace to the immediate caller method, but not both. You are doing both in your method. You are handling the exception, and have declared it to be thrown in the throws
clause too. You should never do that.
Upvotes: 3
Reputation: 7425
try this
try{
ArrayList<String> players = database.LoadUsers();
}catch(SQLException e){e.printStackTrace();}
This is because your loadUsers method is throwing an exception. So, wherever you will call this method you need to surround it with try catch
Upvotes: 0