Reputation: 2881
Okay, so I have a bunch of exception related questions across SO and Programmers, but there's just so much to ask, and either I don't know what to type, or not that many people have asked.
So, let's say I have a method that throws a FileNotFoundException
(FNFE). I then have another method that uses the first one, but also throws a IOException
(IOE).
My handler would catch both and do different things with each, but my IDE (IntelliJ) is signaling I have "a more general exception, 'java.io.IOException', in the throws list already".
I know it works if I do this:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
try {
// Method that generates the FNFE
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
catch (FileNotFoundException fnfe) {
throw fnfe;
}
if (!file.exists())
file.createNewFile(); // IOE
return file;
}
But do I need to do it explicitly? Will it work without, or more dangerously, will sometimes work without the explicit version.
To make sure we are on the same page, this is how I initially wrote the thing:
public File openOrCreate(String pathStr) throws FileNotFoundException,
IOException {
Path path = ReposioryProposition.getPath(pathStr);
File file = path.toFile();
if (!file.exists())
file.createNewFile();
return file;
}
But I am unsure what happens, is the FNFE thrown or swallowed up ? My intention is to catch them separately and do different stuff for one over the other.
Upvotes: 7
Views: 2202
Reputation: 6404
But do I need to do it explicitly? Will it work without, or more dangerously, will sometimes work without the explicit version.
Yes. You have to do it explicitly, because it is a checked exception.
Directly throwing back the exception:
If you just add those checked exception to your methods signature, meaning if you add throws clause in method heading like throws IOException
, then you need not to catch anywhere in your method.
But doing this has one flaw, If you are accessing n files line by line in your code and each line may throw IOException, if the exception is raised. You must close the file .close()
before throwing it back to the called method. So using only this throws clause will not let you to do it.
So, just catch the exception and do necessary action either in catch or finally block.
Only if no action is needed from your side and also if you want the exception to be popped out to the called method and the called method handles it, only then add the throws signature to the method.
Upvotes: 0
Reputation:
Here is what Java Language Specification has to say:
If the run-time type of V is assignment compatible with (§5.2) a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed, and then there is a choice: ...
(Emphasis and ellipsis mine).
Therefore, if you want your more specific catch
clause to be executed, you have to place it first in the catch list.
Upvotes: 0
Reputation: 26856
It's perfectly fine to omit the FileNotFoundException from the throws clause if you already have IOException in it.
Doing so doesn't affect the behaviour at all. FileNotFoundException will still be thrown, and you can catch it explicitly (as well as also having a different, more general, catch of IOException).
Having IOException in the throws clause simply states that IOException or any of its subclasses will be thrown from this method. FileNotFoundException is included in that.
Upvotes: 1
Reputation: 12932
You only have to include the more general exception in your throws
list. This already specifies that the method may throw any subclass of this exception.
In particular, you must handle the more general exception anyway, and this exception handler will also handle the subclass. If you want to handle the subclass explicitly, you have to catch it before the more general exception:
try {
...
}
catch (FileNotFoundException e) {
// handle subclass
}
catch (IOException e) {
// handle general exception (this will not be executed if the
// exception is actually a FileNotFoundException
}
Upvotes: 8
Reputation: 506
you can catch first the sub class exception if not, then the general exception class like this
try{
// something
} catch(FileNotFoundException fne){
// Handle the exception here
} catch(IOException ioe) {
// Handle the IOException here
}
Upvotes: -2