This question already has answers here:
Should methods that throw RuntimeException indicate it in method signature?
(7 answers)
Closed 4 years ago.
Let's say I have the following code:
public void methodOne(String argumentOne) {
methodOne(argumentOne, false);
}
public void methodOne(String argumentOne, boolean equality) {
//App logic here
}
And if the app logic throws an exception (say IllegalArgumentException/Parse Exception), and i would like to catch this in the caller method, should the "throws IllegalArgumentException" be added in all the method identifier or only on the base method identifier? Is there any advantage over this?
Throwing a checked exception means you expect the caller to be forced to think about how to handle that exception. You should only do this when:
This is a deliberate, desirable action in your mind.
You have some idea how you expect the caller to deal with a checked exception. Ideally, you have documented what you expect them to do with the exception.
Thus it's a very bad idea to
declare "throws" an exception which is never actually thrown. This just causes confusion and get the developer into the habit of ignoring your exceptions as they have no value.
throw a checked exception when it is unlikely to be a reasonable way to recover from it. An unchecked exception might be better in that case.
I prefer to add throws clauses for unchecked exceptions as a form of documenting what can go wrong and what it means without forcing the caller to handle those exceptions.
Additionally, you should try to add meaningful messages to each Exception/Error to make it easier for a developer to work out how to fix the code or configuration.
i would like to catch this in the caller method, should the "throws IllegalArgumentException" be added in all the method identifier or only on the base method identifier?
Only add it to the methods which can actually throw the exception.
Related
The below picture shows that "Checked" and "Unchecked" Exceptions are subclasses of Exception. I find it confusing that you need to catch an Exception but you don't need to catch a RuntimeException, which directly inherits from Exception. Is there a reason that the devs didn't let us throw Exceptions without needing to catch them?
More specifically: Why can you ignore only RuntimeExceptions and it's children? Why wasn't there a Class introduced called CheckedException extends Exception and you only need to catch it and it's children?
The confusing part is, that you can throw everything below RuntimeException without issue, but when you move up to Exception in the hierarchy, you need to catch it at some point. This is confusing because "abstraction" normally works otherwise. The more you move up, the simpler and more meta everything gets. This is not the case here. The more you move up, the more you have to do (like, putting try/catch after reaching Exception).
If Exception was unchecked then you could implicitly cast checked exceptions to unchecked ones, which would mean that you could throw checked exceptions without catching them like:
public void f() {
Exception e = new IOException();
throw e;
}
and also with overriding methods, if you throw a more specific exception, you can add the requirement to catch the exception that wasn't in the superclass:
public void f() throws Exception {
}
...
#Override
public void f() throws IOException {
}
Suppose they designed it the other way. We have a CheckedException class, and subclasses of that need to be handled, but not other subclasses of Exception.
Now we call a method that might throw an arbitrary Exception:
public static void example() {
functionThatThrowsException();
}
Do we need to handle it? Yes, because that Exception might be a CheckedException. If we didn't need to handle it, we'd be bypassing the checked nature of checked exceptions.
A throwable type with checked descendants must be treated as checked, so checkedness naturally propagates up the inheritance hierarchy. Contrapositively, an unchecked throwable type cannot have checked descendants, so uncheckedness naturally propagates down. This makes it natural to make checkedness the default, and single out specific classes and their descendants as unchecked.
CheckedException (Which does exist) and RuntimeException both extend Exception. Because of this, if something throws a generic Exception (which is always a bad idea), there is no way to tell if the exception could be one or the other, so you have to catch it in case it's a checked one. If you think of the hierarchy in this way, it actually does get simpler the farther up you go.
You seem to have the idea that checked exceptions are more "complex" because you have to do more to work around them. This isn't too healthy a way of thinking about it. Instead, consider this: Exceptions are problems with the program itself - the code. We need to find these exceptions and handle them properly. After already having this concept of exception handling, we discover that there are some problems that we simply can't predict.
"How was I supposed to know the user would enter 'meow' when asked for an integer! I shouldn't have to code around that!" And so, NumberFormatException was born, and you don't have to catch it because it's a "logical error", not an issue caused by bad code (Although, arguably, it might be considered bad code if you don't handle this situation in some way).
In short, reverse your thinking. Exceptions are problems with the program that can be handled. There are some exceptions, however, that are unexpected and are a result of bad design more than incorrect code. Thus there is the addition of RuntimeExceptions which cannot possibly be expected to occur, but certainly can occur.
Perhaps it would help to not think of exception classes in terms of inheritance but simply disjoint sets of classes, one set is checked and other is not. You're right that there could be a CheckedException class allowing us to check only when explicitly intended.
However having the broader/generalized range checked helps in enforcing the catch or specify pattern. Having checked exception allows a reader of the code to figure out quickly that this piece of code needs special attention and enforcing their handling at compile time reducing the runtime bugs.
We can throw any kind of exception, checked or unchecked. If Exception or any super class of RuntimeException were to be set as checked exception then all the sub classes would become checked exceptions. As compiler is most likely checking if an instance of exception or a class in the throws clause derives from a class. It could easily have done that by checking for a specific package which probably would have been more appropriate as being checked or unchecked has simply nothing to do with the inheritance.
Why throws, on a method, is part of its signature? It seems strange to include it. Here is an example where it is in the way:
#Overide
public void foo() {
throw new UnsupportedOperationException();
}
If anyone were to see this method from the outside, they might try to use it without knowing that it is not supported. They would only learn it on trying to run the code.
However, if they could do something like this they would know by looking at the method that it is not supported and if UnsupportedOperationException was not extending RuntimeException, they would get a compilation error. EDIT1: But this is not possible because throws is part of the signature so override will not work.
#Overide
public void foo() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
This question concerns Java's design, so I know that it might be hard to answer without one of the people that work on it drops by and answers it, but I was hoping that maybe this question has been asked to them before or that there might be an obvious reason to have it this way to explain why.
The throws part does not indicate that the method is required to throw the mentioned exception(s), not even at particular occasions. It only tells that the function is allowed to do so.
Including throws UnsupportedOperationException will consequently not mean that the method is unsupported. Besides the UnsupportedOperationException is a RuntimeException so a method may throw that anyway.
Now for the reason one would require it in the signature of the method, it boils down to the ability to have checked exceptions at all. For the compiler to be able to decide if a method can only throw the specified exceptions it must be able to decide that the methods that it calls can't throw uncaught exceptions.
This means for example that overriding a method means that you can't add exceptions that might be thrown, otherwise you would break the possibility to verify that a method that calls that method can't throw anything else than it has specified. The other way around would be possible (but I'm not sure if Java supports that), overriding a method that may throw with one that may not throw.
So for example:
class B {
int fubar(int) throws ExceptionA {
}
int frob(int) throws ExceptionA {
return fubar(int);
}
}
class D extends B {
int fubar(int) throws ExceptionB {
}
}
Now frob is specified to possibly throw only ExceptionA, but in calling this.fubar it would open the possibility that something else is thrown, but fubar is defined to possibly only throw ExceptionA. That's why the D.fubar is an invalid override since that would open up the possibility that this.fubar actually throws ExceptionB and the compiler wouldn't be able to guarantee that frob doesn't throw ExceptionB.
Java has two different types of exceptions: checked Exceptions and
unchecked Exceptions.
Unchecked exceptions are subclasses of RuntimeException and you don't have to add a throws declaration. All other exceptions have to be handled in the method body, either with a try/catch statement or with a throws declaration.
Example for unchecked exceptions: IllegalArgumentException that is used sometimes to notify, that a method has been called with illegal arguments. No throws needed.
Example for checked exceptions: IOException that some methods from the java.io package might throw. Either use a try/catch or add throws IOException to the method declaration and delegate exception handling to the method caller.
One thing which no one has mentioned is a very important answer to your question:
Why throws, on a method, is part of its signature?
that throws, is NOT part of the method signature.
JLS 8.4.2. Method Signature makes it quite clear, that:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (ยง8.4.4), and, after adapting the formal parameter types of N to the type parameters of M, the same formal parameter types.
If anyone were to see this method from the outside, they might try to use it without knowing that it is not supported.
That's exactly the main reason, why throws is designed in a way to be checked at compile-time for all Checked Exceptions - clients of the method will be aware what this method may possibly throw.
Checked Exceptions are enforced to be either handled or specified to be thrown (but this specification is NOT part of the method signature).
Unchecked Exceptions do not have to be either handled or specified to be thrown, and Oracle's tutorial are good at explaining - why:
Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.
This question already has answers here:
In Java, when should I create a checked exception, and when should it be a runtime exception? [duplicate]
(14 answers)
Closed 4 years ago.
I am doing a code review and I have came across this method definition:
public void something() throws RuntimeException
Is there a rational reason to write 'throws RuntimeException' in Java?
RuntimeException is unchecked exception and therefore can be thrown from any place in the code. Saying "Hey, this method can throw RuntimeException" and knowing that any piece of code can do so may be redundant. The only reason I can think of, you would like to make it explicit is for documentation purposes, eg. "Throws RuntimeException when some specific thing happens", but then it probably belongs to javadoc, not to method signature.
Everything is context-dependent, of which you shared none; but on a general note in may be said that this very rarely makes sense. Methods declare unchecked exceptions for documentation purposes, but these are normally specific exceptions carrying some domain-specific meaning. Declaring to throw a completely generic unchecked exception is thus quite hard to justify, although I cannot say there is absolutely no situation where it may make sense.
Runtime exceptions represent problems that are the result of a programming problem, and as such, the API client code cannot reasonably be expected to recover from them or to handle them in any way. Such problems include arithmetic exceptions, such as dividing by zero; pointer exceptions, such as trying to access an object through a null reference; and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.
This types of exceptions depend directly of code, for example, "ArrayIndexOutOfBoundsException".So, if you don't use arrays, arraylists, casting or something what could throw a RuntimeException, it wouldn't be neccesary to write that.
Any method can throw RuntimeException, like NullPointerException being most common. So if a method throws RuntimeException (or it's subclass), it's usually not put that in method signature.
So according to me, it just shows inmaturity of the programmer as it doesn't add any value. Though, it's not asked but even the method name i.e. something() is fishy. It doesn't convey any meaning to the reader.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
The Java specification requires that if an exception is thrown, it is either handled by a try/catch statement, or that the function is declared with "throws XYZException". This has the exception of RuntimeException, where it is OK if this is thrown without being caught.
This might sound like a matter of opinion, but the more I think about it, the more it seems really counter-intuitive:
Why is it that we have a RuntimeException extending Exception?
When I first started doing Java, I thought ALL exceptions had to be caught in that way, and it made sense because all exceptions extend Exception. It seems like a violation of OOP to have a RuntimeException exception exception :P. Since RuntimeException makes throws kinda redundant, why didn't Java allow all exceptions at runtime in the first place, adding a throws only when you want to force the caller to handle that type of exception?
Examples:
void noThrows() {
throw new Exception();
}
... no errors.
void hasThrows() throws AnyBaseOfXYZException {
throw new XYZException();
}
... no errors.
void testFunction() {
hasThrows();
}
... fails since "hasThrows" throws AnyBaseOfXYZException, and this is not handled
void testFunction() {
try {
hasThrows();
} catch (AnyBaseOfXYZException e) {
...
}
}
... no errors.
I'd thought about maybe some kind of "CompileTimeException" that extends Exception, but when you give it enough thought, it just can't work without being as ugly as RuntimeException.
Basically, why did Java decide to force all exceptions to require throws except for RuntimeExceptions, when all exceptions could be runtime exceptions except when otherwise stated with throws?
Firstly, the base class of all things that can be thrown is Throwable (not Exception).
Under Throwable are two subclasses: Exception and Error.
Under Exception is RuntimeException.
Of these 4 main classes, RuntimeException and Error are unchecked (may be thrown without having to be declared as being thrown).
The idea behind RuntimeException being unchecked is that it's typically a programming error and that normal good practice should avoid them (eg ArrayIndexOutOfBoundsException or NullPointerException) and to require them to be caught would clutter up the code massively.
The reason Errors are unchecked is that basically, there's nothing you can to about it if one happens, eg OutOfMemoryError etc.
That leaves all other Throwables, ie subclasses of Exception, must be declared as thrown or caught. The idea behind this is that checked exceptions can be "handled by the caller". eg FileNotFoundException (we know what this means and should know what to do if we get one).
The Java designers didn't always get this right. SQLException is checked, but there's no realistic way to recover - do I have a syntax error in my query? is the database refusing conections? who knows, but I do know I can't "handle" it.
In some cases you want to have a catch that catches all exceptions: checked and unchecked.
Java's design decision allows you to achieve that with catch (Exception e) { ... }
If unchecked exceptions (exceptions that extends RuntimeException) were not extending Exception then you had to use two catch clauses.
This might be related to topic of check and uncheck exception. From RuntimeException
RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions
do not need to be declared in a method or constructor's throws clause if they can
be thrown by the execution of the method or constructor and propagate outside the
method or constructor boundary.
Check exception is to be use for case that recoverable when the program is executed. So it makes perfect sense to force programmer writing the class to declare it in a method definition. By doing so the caller will be force to catch it or re throw it.
However uncheck exception is for a case that is unrecoverable and thus it is better to terminate. This case is rarely happen (usually happen when the code is still being developed) and thus this usually indicate a programmer error or a very fatal bug that usually need to fix by the class writer and is not recoverable by the client of the class.
This question already has answers here:
Checked vs Unchecked exception
(7 answers)
Understanding checked vs unchecked exceptions in Java
(21 answers)
Closed 9 years ago.
I've been doing some pure Java development recently, and I'm using an external lib that exposes a small number of methods, each of which have the possibility of throwing an Exception.
Eclipse won't let me compile my program unless I wrap each of those calls in a try-catch block. So far, no big deal.
Then I noticed some things, like ArrayList.add(), which throws IndexOutOfBoundsException. How is it that I can call something like this without needing to wrap it in a try..catch? Obv, in this particular case, it would be incredibly irritating if you had to do it each time, but how and why is try-catch enforced in some situations, but not others?
Unchecked exceptions (subclasses of Error or RuntimeException) need no try..catch block, and when there is no try...catch, the method need not to declare itself to be throws (you can, of course, and some consider declaring throws to be a good practice) . On the other hand, checked ones do need the try...catch, or declares throws.
IndexOutOfBoundsException is an unchecked exception, i.e. it extends RuntimeException or Error, or sub class of either, therefore a try/catch block is unnecessary. From the docs:
Checked exceptions are subject to the Catch or Specify Requirement. All exceptions are checked exceptions, except for those indicated by Error, RuntimeException, and their subclasses.
In contrast, checked exceptions require a try/catch block otherwise a compiler error will result.