简体   繁体   English

函数抛出异常时的返回类型可以是Exception

[英]Function's return type can be Exception when it throws Exception

Let's say I have a function假设我有一个功能

private RuntimeException foo() {
    return new RuntimeException();
}

and exception there is not thrown and it can be processed like并且没有抛出异常,可以像这样处理

throw foo();

or return value can be assigned to a variable或返回值可以分配给变量

RuntimeException e = foo();

But the function can be changed to但是函数可以改成

private RuntimeException foo() {
    throw new RuntimeException();
}

and it still compiles and can be used like in previous examples or can just be called like foo();它仍然可以编译并且可以像前面的例子一样使用,或者可以像foo();一样被调用foo(); and Exception will be thrown.并且会抛出异常。

But why is it possible to specify RuntimeException as a return type of a method that doesn't return it but throws it instead.但是为什么可以将RuntimeException指定为不返回它而是抛出它的方法的返回类型。 Is there any connection between throw and return behavior in this case?在这种情况下,throw 和 return 行为之间是否有任何联系?

I've noticed that having Exception (or more generally Throwable ) return type ensures that it will be thrown/returned in every decision branch like if/else statements.我注意到具有Exception (或更普遍的Throwable )返回类型确保它将在每个决策分支中抛出/返回,如 if/else 语句。 But is there any more practical usage or recommended of this?但是有没有更实际的用法或推荐呢?

Since throw will make the execution of the method stop immediately and control is passed back to the caller, it doesn't matter what your method returns.由于throw将使方法的执行立即停止并且控制权被传递回调用者,因此您的方法返回什么并不重要。 No matter what type you return, that type will not be returned, because you are throwing an exception (which indicates something wrong happened) on the first line.无论您返回什么类型,都不会返回该类型,因为您在第一行抛出异常(表示发生了错误)。

The compiler allows this because throwing an exception means something wrong happened, like the arguments are invalid, or the argument is null, and so on.编译器允许这样做,因为抛出异常意味着发生了错误,比如参数无效,或者参数为空,等等。 In such error conditions, the compiler does not expect the method to return a value normally.在此类错误情况下,编译器不希望该方法正常返回值。 It makes sense because obviously when something wrong happens, the method can't compute whatever it is that it was going to compute.这是有道理的,因为很明显,当发生错误时,该方法无法计算它要计算的任何内容。

So the phrase "all code paths must return a value" should really say "all code paths must return a value or throw a Throwable ".所以短语“所有代码路径必须返回一个值”应该真正说“所有代码路径必须返回一个值或抛出一个Throwable ”。

There is no relation between what a method returns and what it can throw.方法返回什么和它可以抛出什么之间没有关系。 and there are use cases where a method may both return and throw an exception.在某些用例中,方法可能既返回又抛出异常。

consider the following scenario: a method that is called to produce an application-specific exception:考虑以下场景:一个被调用以产生特定于应用程序的异常的方法:

public Exception produceException(User u) {
    if (u.id == null) return new UserNotFoundException();
    if (u.name == null) return new UserDidNotCompleteRegistrationException();
    if (u.email == null) return new UserDidNotVerifyEmailException();
}

now guess what will happen if the argument itself is null ?现在猜猜如果参数本身为null会发生什么? and the method does not even declares a throws clause...并且该方法甚至没有声明throws子句......

now, regarding having Exception as return value for the sake of ensuring that an exception is returned at every branch is just bad design.现在,为了确保在每个分支都返回异常而将 Exception 作为返回值是很糟糕的设计。 return value is not the mechanism to be used for throwing exception.返回值不是用于抛出异常的机制。 if you surround the entire method body with try-catch you will catch all exceptions from all branches.如果你用 try-catch 包围整个方法体,你将捕获所有分支的所有异常。

why is it possible to specify RuntimeException as a return type of a method that doesn't return it but throws it instead.为什么可以将 RuntimeException 指定为不返回它而是抛出它的方法的返回类型。 Is there any connection between throw and return behavior in this case?在这种情况下,throw 和 return 行为之间是否有任何联系?

It's possible to specify any type as a return type of any method.可以将任何类型指定为任何方法的返回类型。 There is no connection between return and throw behavior.返回和抛出行为之间没有联系。

I've noticed that having Exception (or more generally Throwable) return type ensures that it will be thrown/returned in every decision branch like if/else statements我注意到具有 Exception(或更一般的 Throwable)返回类型确保它会在每个决策分支中抛出/返回,如 if/else 语句

No, that's not the case.不,事实并非如此。 There is no way to "ensure [an Exception] will be thrown in every decision branch".没有办法“确保在每个决策分支中都会抛出[异常]”。 The only thing you can do is to state "this method may throw an Exception by using the throws keyword:您唯一能做的就是声明“此方法可能会使用throws关键字抛出异常:

public void mightThrowException() throws Exception {...}

but there's no guarantee that any exception will be thrown at all.但不能保证任何异常都会被抛出。

BTW, there are two types of exceptions: checked and unchecked.顺便说一句,有两种类型的异常:已检查和未检查。 Unchecked exceptions are subclasses of RuntimeException ;未经检查的异常是RuntimeException子类; those do not need to be declared for your method.这些不需要为您的方法声明。 Checked exceptions do, so受检异常可以,所以

public void throwsIoException() {
    throw new IOException();
}

is illegal because IOException is a checked exception that needs to be declared with throws .是非法的,因为IOException是需要用throws声明的已检查异常。

You mixed something up with your example.你把一些东西和你的例子搞混了。 Because when throwing an exception in a method the return type is not really considered, so instead of declaring the method like in your example.因为在方法中抛出异常时,并没有真正考虑返回类型,所以不要像在您的示例中那样声明方法。 you could also declare it like the following:你也可以像下面这样声明它:

public void foo(){
    throw new RuntimeException();
}

or:或者:

public MyComplexType foo2(){
    throw new RuntimeException();
}

The result is simply the same: An exception is thrown.结果是一样的:抛出异常。 The calling code just will look differently eg:调用代码看起来会有所不同,例如:

foo(); // throws RuntimeException
myOtherComputation(); // is never reached

or或者

MyComplexType type = foo2(); // throws RuntimeException
type.doSomething(); // is never reached

This behaviour can be useful when using for example a switch statement in a method but throwing an error when entering the default branch:例如,当在方法中使用switch语句但在进入默认分支时抛出错误时,此行为可能很有用:

public String foo(String string){
    switch(string){
        case "foo":
             return "bar";
        case "bar":
             return "foo";
        default:
            throw new UnsupportedOperationException("Unknown string: '" + string + "'!");
     }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Return.map lambda 和抛出异常的 function - Return .map lambda with function that throws exception 在具有返回类型的方法中,return语句是可选的,它不是无效的,但会引发异常? - Is return statement optional in a method that has return type not void, but throws an Exception? 调用函数时为什么需要“抛出异常”? - Why is “throws Exception” necessary when calling a function? 异常可以引发相同的异常吗? - Can a exception throws the same exception? 使用Mockito,如何使用返回类型void存储一个方法,该方法在传递某个参数时会抛出异常? - With Mockito, how to stub a method with return type void which throws an exception when a certain argument is passed? 什么时候抛出“ throws Exception”? - When is “throws Exception” thrown? Java方法在抛出异常时返回JNI调用方的内容是什么? - What does a Java method return to a JNI caller when it throws an exception? 为什么java允许一个总是抛出异常的方法将返回类型声明为异常? - Why does java allow a method which always throws an exception to declare the return type as that exception? Jackson 将Object转String,属性类型为Integer,getter返回int,当属性为null时,抛出null点异常? - Jackson Convert Object to String, property type is Integer, and getter return int, when property is null ,then throws null point exception? 如果我们在方法签名中抛出子类型异常,是否可以在方法中抛出Parent类型异常? - Can we throw Parent type exception in the method if we written throws child type exception in the method signature?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM