0

Say i have one method 'position', which takes 2 co-ordinates and creates a position object to hold them in. To make sure that these co-ordinates are not out of bounds, an InvalidPositionException is thrown.

public Position(int x, int y) throws InvalidPositionException {
    try {
        if (x > 10 || x < 1 || y>10 || y<1) {   
            throw new InvalidPositionException("Position x = "+x+", y = "+y+" is out of bounds");
        } else {
            setX(x);
            setY(y);
        }
    } catch (InvalidPositionException e) {
        System.err.println(e);
    }
}

If I now want to create a new position object from another class, I get the error message "unreported exception InvalidPositionException; must be caught or declared to be thrown"

How can I make this work without declaring "throws" in the method signature of the method creating the new position object?

Turing85
  • 18,217
  • 7
  • 33
  • 58
Jaxon
  • 17
  • 8
  • 2
    Take a look at [Oracle's lesson on `Exception`s](https://docs.oracle.com/javase/tutorial/essential/exceptions/). – Turing85 May 03 '18 at 22:00
  • why you need *throws InvalidPositionException* in your constructor declaration if you are catching it? it won't throw it.. – xagaffar May 03 '18 at 22:31

3 Answers3

1

Go to the class InvalidPositionException and make it inherit from RuntimeException.

RuntimeExceptions are unchecked exceptions, meaning that the compiler does not force you to deal with them. A good example of this when you go out of bounds from your array. You don't have to write code that deals with this issue every time you access an array (like how we handle IOException). A similar example is NullPointerException. In both cases, however you could write code to catch the exception and handle it.

Another way to deal with the problem if you are a checked exceptions purist and don't want a try-catch block is to sanitise the data in whatever screen you input the data and say that it is out of bounds there.

ifly6
  • 5,003
  • 2
  • 24
  • 47
  • 1
    Oh no. No. Nono. Nonono. Don't do that. That defeats the whole point of the `catch-or-throws` principle. – Turing85 May 03 '18 at 22:01
  • I don't want to wade into the Checked exceptions debate that has been churning on the Internet since... (looks into the air a la Darth Vader) Java was released, but it seems clear to me we're on opposite sides of it. – ifly6 May 03 '18 at 22:14
1

From Effective Java by Joshua Bloch

Item 72: Favor the use of standard exceptions

An attribute that distinguishes expert programmers from less experienced ones is that experts strive for and usually achieve a high degree of code reuse. Exceptions are no exception to the rule that code reuse is a good thing. The Java libraries provide a set of exceptions that covers most of the exception-throwing needs of most APIs. ...

IllegalArgumentException occasions for use - Non-null parameter value is inappropriate

This code is a classic example the IllegalArgumentException was created for. It extends RuntimeException so you are not required to catch it.

public Position(int x, int y) {
    if (x > 10 || x < 1 || y>10 || y<1) {   
        throw new IllegalArgumentException("Position x = "+x+", y = "+y+" is out of bounds");
    } 
    setX(x);
    setY(y);
}

P.S. you probably can just replace setX(x) by this.x = x and the same for y (if there's no extra logic in those setters).

Community
  • 1
  • 1
xagaffar
  • 683
  • 8
  • 16
  • I think this is a good answer. But it runs into the so-called "problem" that the exception isn't required to be checked. – ifly6 May 04 '18 at 17:19
  • @ifly6 ah it's a big debate indeed.. How would it be useful to use a checked exception here? Let's assume invalid parameters were sent, then the client catches the exception, then either tries to instantiate with different params inside another try-catch..or log error and escape whole logic using the instance? – xagaffar May 04 '18 at 20:10
0

You need to include a try-catch block around the statement which creates the Position object.

Position myPosition = null;
try {
  myPosition = new Position(a, b);
}
catch (InvalidPositionException e) {
  // do something if the exception is caught
}
Bryan
  • 186
  • 10
  • When i do this, the object variable is scoped within the try block, so i can't use this outside, yet if I initialise it outside of the try block, I have the same problem. In this case, would i have to use Position myPosition = null; Before the try block and remove the type from inside it? – Jaxon May 03 '18 at 22:13
  • If you mean `myPosition = new Position(a, b)` when you say 'remove the type', yes. – ifly6 May 03 '18 at 22:15
  • Yes, my mistake. Declare the variable outside the try block and initialize it to null. I edited in my answer. – Bryan May 03 '18 at 23:04