Why do you need to catch “Exception” but not the Subclass “RuntimeException”?

假如想象 提交于 2021-01-27 01:30:13

问题


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).


回答1:


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 {
}



回答2:


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.




回答3:


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.




回答4:


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.




回答5:


Your picture already contains an answer - Throwable is checked and must be caught, because of that Exception is checked and so on, besides RuntimeException and its descendants.

Checked exceptions must be caught or rethrown (JLS §11.2). This is guaranteed by java compiler so we are ensured that our "exceptional" situation will be handled.

This compile-time checking for the presence of exception handlers is designed to reduce the number of exceptions which are not properly handled.

If you inverse the logic, then you can't give these guarantees at compile time:

public void notReallySafeMethod() {
    try {
        connect();
    } catch (IOException io) {
        Exception e = io;
        throw e; // IOException is unhandled
    }
}

public void suspiciousMethod() throws Exception {};

public void callSuspicious() {
    suspiciousMethod(); // what real type would be thrown? we can't know
    //  should I try-catch everything then?
}


来源:https://stackoverflow.com/questions/37170572/why-do-you-need-to-catch-exception-but-not-the-subclass-runtimeexception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!