Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What to return on an IndexOutOfBoundsException exception?

Tags:

java

I have the following method

private ArrayList<User> allUsers = new ArrayList<User>();

public User getUser(int index) {
    try {
        return allUsers.get(index);
    }
    catch(IndexOutOfBoundsException e) {
        // What should I return here?? Say that you want index 0 and no User
        // exists in the ArrayList allUsers, what should I then return? The
        // method needs a User to be returned 
    }
}

And I'm not sure how to do here, I'm sure thats its an easy fix, but what should I return in the catch block? Eclipse is complaining that a User must be returned.

like image 829
user1825441 Avatar asked Nov 27 '22 23:11

user1825441


2 Answers

My general opinion is that you should never catch an exception that you don't know how to handle. Particularly in this case, since IndexOutOfBoundsException is a RuntimeException and thus does not need to be caught - you can just as well let it propagate up the call stack. The caller is asking for an object by list index, so presumably has some idea of which index to ask for -- then, throwing or allowing a thrown IndexOutOfBoundsException to propagate seems perfectly natural.

The only other obvious option would be to swallow the exception and return null, but I really don't like such an approach for such flagrant errors on the part of the caller when there is no sensible return value. You could also return a special User instance (refer null object pattern), but even that does not absolve the caller of the responsibility to check what was returned. Depending on the interface and implementation of User such checks may be trivial or not, but it still needs to be done somewhere.

If you want to be clear that the method can throw an exception, just say so:

public User getUser(int index) throws IndexOutOfBoundsException { ... }

Or like @Bela Vizer suggested, wrap it in an IllegalArgumentException (which also is a RuntimeException).

And as pointed out by @lc., it's better to check first yourself if the object exists before trying to access it. Handle yourself the error case that you expect rather than relying on the get() method call to throw an exception. You should still be clear about the fact that the method might throw such an exception, however, if for example the collection is modified between the check and return. With multithreaded software on multi-core CPUs, stranger things have been known to happen.

like image 192
user Avatar answered Dec 16 '22 03:12

user


Ask yourself the question: "what should you return if you want index 0 and no User exists?" and return whatever you answer.

If you have no answer, you should either re-throw the exception or not be catching it in the first place.

Note that often times, the answer would be to return null, if it is acceptable behavior to ask for a non-existent User.


Side comment: It is usually considered "good practice" to not rely on catching exceptions, but to test for error conditions first. In your case you are trying to get an invalid object index first then reacting if the getter blows up. Instead, I would recommend to test the index parameter first (make sure it is at least zero and less than the length of allUsers), and if it fails the test to do something (return null or throw your own exception).

like image 37
lc. Avatar answered Dec 16 '22 03:12

lc.