简体   繁体   中英

Why method that calls another one which throws RuntimeException needs return statement?

Why unreachable statement is not identified by javac ?

public int directThrow(){
     throw new RuntimeException();
    //Compiles fine
}

public int indirectThrow(){
    directThrow();
    // Missing Return Statement error
}

The compiler simply isn't designed to analyse your code that deeply.

For directThrow , the compiler looks at it and says, "I see you have a throw statement, so the method will terminate abruptly here, no need for a return statement then!"

For indirectThrow , the compiler looks at it and says, "I only see a method call. Hey programmer! You need a return statement here!"

The compiler doesn't look at what directThrow actually does. I think this is quite reasonable, because the benefit of analysing what every method you call does is really small, compared to the cost of increased compilation time. Think about what the compiler needs to check to make sure that directThrow will always throw an exception. The most important thing being, is it overridden by anything? Can you even check that? Can you even make sure that no class in the future will subclass your class and override that method (give your class and directThrow are both non- final )?

If you have some complicated exception-throwing logic that you want to extract into a method, you can extract it into a method that returns the Exception :

private Exception someComplicatedLogicThatGivesAnException() { ... }

public void foo() {
    if (...) {
        throw someComplicatedLogicThatGivesAnException();
    }
}

Counter question: What if directThrow() was somehow altered that it doesn't throw an exception? How should the code then handle that?

To illustrate this problem, here's an example:

class Foo {
    int throwSomething() {
        throw new RuntimeException();
    }
}

class Bar extends Foo{
    int throwSomething() {
        return 1; // hahaaa, we don't throw but return normally
    }
}

See? The subclass overrides the base method, and returns something, how should the code now handle that:

int indirectThrowing(Foo foo) {
    foo.throwSomething();
}

If we pass new Foo() it will throw as expected, but if we pass new Bar() it will just return 1 . And thus it will not fail.

To overcome this problem, you must write a return statement. Or if you want to reuse what you already have, you can also write:

return directThrow();

Because directThrow() has a return type int , and thus you just pass the argument upwards.

Note, some languages like Kotlin handle this with a Nothing (sometimes called also Never ) return type. To indicate to the compiler that a method can never return normally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM