When should we use throws keyword in Java? [duplicate]
Asked Answered
L

4

6

throws keyword is used only for checked exception. It instructs the caller to use try catch block to except all the listed exceptions by throws keyword.

Since we know what kind of checked exception might occur in our module, then:

  1. Why don't we use try catch block inside the module to handle the checked exceptions?
  2. Can we handle checked exceptions inside the module using try-catch block?
  3. If answer of (2) is YES, then Why we are forcing the caller to except those exceptions using throws keyword, when we could except the same inside the module itself?

In that way we need not to manually except the exceptions every time the method is called.

Leper answered 25/5, 2019 at 9:4 Comment(2)
"throws keyword is used only for checked exception" - note that you can use it for unchecked exceptions as well, just in case you did not know.Excursionist
A method can not always decide what the best way to react to an exceptional situation should be. Then it is the time for the user of your method to define the error-handling. Imagine having a openFile method but the file does not exist. There is no way for the openFile method to solve this, the user must do it.Excursionist
M
5

Let me use FileInputStream::new throwing FileNotFoundException as an example to clear up your misunderstanding.

So for example we have some code like this:

FileInputStream fis = new FileInputStream("/some/path/to/file.txt");

That might throw a FileNotFoundException, and you are saying that,

FileInputStream obviously knows that it is going to throw a FileNotFoundException, so why does it not handle it itself?

Because FileInputStream does not know how to handle the exception!

Depending on the situation, there are lots of ways to handle a FileNotFoundException:

  • If the file path comes from user input, you might ask the user to enter another file path
  • You might display an error message
  • You might not do anything and just let it crash

All of the above could be completely sensible options depending on the situation. How is a FileInputStream going to know about your situation? It's not!

That's why it's saying, with a throws clause:

I'm throwing these exceptions, handle it yourself.

Metallist answered 25/5, 2019 at 9:17 Comment(0)
T
5
  1. It is all about how to recover from an exception. What should e.g. java.lang.File do when the file does not exist? As it doesn't know what would be the best for the callee, it lets the callee handle this case
  2. Of course you can handle exceptions in your module if its clear how said exceptions should be handled. If the handling is dependent on the callee or context, let the calling function decide
  3. Should be clear by now
Tizzy answered 25/5, 2019 at 9:14 Comment(0)
M
5

Let me use FileInputStream::new throwing FileNotFoundException as an example to clear up your misunderstanding.

So for example we have some code like this:

FileInputStream fis = new FileInputStream("/some/path/to/file.txt");

That might throw a FileNotFoundException, and you are saying that,

FileInputStream obviously knows that it is going to throw a FileNotFoundException, so why does it not handle it itself?

Because FileInputStream does not know how to handle the exception!

Depending on the situation, there are lots of ways to handle a FileNotFoundException:

  • If the file path comes from user input, you might ask the user to enter another file path
  • You might display an error message
  • You might not do anything and just let it crash

All of the above could be completely sensible options depending on the situation. How is a FileInputStream going to know about your situation? It's not!

That's why it's saying, with a throws clause:

I'm throwing these exceptions, handle it yourself.

Metallist answered 25/5, 2019 at 9:17 Comment(0)
P
1

sometimes you want to manage some exceptions in another part of the application.

For example you can have a package which will only send a request to the internet, and bring back the response. If you use this package as lib in both a headless server app and a desktop app with user interface, you'd want to manage the to exception differently. Logging it and retry for the headless app and display an error message and a retry button for the desktop app.

If you manage the exception at the net package only, you can't have this, if you throw the exception, the rest of the app can deal with it as you want.

There is other use case here this can be useful, if you don't know how your package will be used (so you or someone else can choose how to deal with it later)

The general idea is to decouple pure code logic, and exception management.

Penick answered 25/5, 2019 at 9:13 Comment(0)
R
1

Note that you can also re-throw an exception. In many cases, it is perfectly reasonable to pass the error on to the next layer. If you also add a throws IOException to your method, then it does not have to handle it. In many cases, the only way to handle such failures is to fail, and that should usually be done at the outermost level.

IDEs will remind you of missing throws and suggest possible ways of resolving this. So the effort for the developer is pretty light compared to the benefit of having defined behavior on failure.

However it should be clear that the IDE not the compiler can predict the future, or the proper abstraction.

First of all, an interface or an abstract method can - and should - declare exceptions. For example:

interface Opener {
    InputStream open(String id) throws IOException;
}

Reminding the user of this interface to handle such errors, for example file not found exceptions.

Furthermore, the compiler or IDE don't know the proper abstraction. Your code may do a

if (httpcode == 404)
  throw new FileNotFoundException("Server returned a 404 error.");

But you don't know yet if you'll maybe later change this to a different exception, because it's not really a file. For example, you may want to have a subclass of a network exception. However, you may be sure that all exceptions that you intend to throw will be IOExceptions, and hence require the user of that method to handle it at this level.

Receive answered 25/5, 2019 at 10:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.