如何通过使用条件 return 从 try、catch 和 finally 得到一个值?

How to return a value from try, catch, and finally by using condition?

我的 get() 方法用红线标记,它告诉我

this method must return a result of type char

public char get() {
    mutex.lock();
    char c = buffer[out];
    try {
        while (count == 0) {  
            okConsume.await();
        }
        out = (out + 1) % buffer.length;
        count--;
        System.out.println("Consuming " + c + " ...");
        okConsume.signalAll();
        return c;
    }catch(InterruptedException ie) {
        ie.printStackTrace();
    }finally {
        mutex.unlock();
    }
    
}

您的代码应该涵盖所有可能的场景。现在不是了,因为如果发生异常,您没有return从该方法中退出。

放置在try中的return语句在异常情况下将无法访问。

关于Exception-handling的更多信息,我建议看看 this tutorial.

有两种修复方式:

  • trycatch 块中放置 return 语句;
    public char get() {
        mutex.lock();
        char c = buffer[out];
        try {
            // some code
            return c;
        } catch (InterruptedException ie) {
            ie.printStackTrace();
            return c;
        } finally {
            mutex.unlock();
        }
    }
  • 将 return 语句放在 finally 块之后;
    public char get() {
        mutex.lock();
        char c = buffer[out];
        try {
            // some code
        } catch (InterruptedException ie) {
            ie.printStackTrace();
        } finally {
            mutex.unlock();
        }
        return c;
    }

不确定 'by using condition' 是关于什么的。但是,从您的代码片段中可以清楚地看出问题。

你的异常处理很烂.

没关系。出于一些奇怪的原因,大多数例子,据我所知,每个主要 IDE 都搞砸了,所以这不是你的错。问题是,ie.printStrackTrace() 可怕的 ,永远不应该这样写。这不是您处理异常的方式 - 即使是您不想考虑的异常。

这里的具体问题是真正的意思:这个:

} catch (Something e) {
  e.printStackTrace();
}

的意思是,从字面上看:每当问题 X 发生时,打印有关 X 的一半信息(特别是使用一个谎言的方法名称 - printStackTrace 不打印堆栈跟踪,它打印的方式比那。使用错误命名的方法是一种糟糕的形式),将另一半扔进垃圾桶,然后继续

这就是问题所在:如果发生异常,打印一半有关问题的信息并继续。继续……什么?方法结束 - 因此,编译器正确地抱怨:它不知道 return 是什么,而你告诉它 'keep going'.

修复很简单。选择其中一项:

  1. 首选解决方案:正确处理异常。这并不像你想象的那么难。
  2. 'eh whatever I do not want to think about it' 解决方案需要始终是:throw new RuntimeException("uncaught", e); 而不是 e.printStackTrace()。修复您 IDE 的模板!

在这种特定情况下,'fix it properly' 非常简单。 InterruptedException 不可能发生,除非您显式编写一些代码来调用线程对象的 interrupt() 方法。你这样做的可能性很小,但如果你这样做,你有一个特定的理由。不管那是什么 - 对其进行编程。中断点是把await方法打断出来,到'short circuit it'。那你想发生什么?也许这个方法通过异常退出,在这种情况下,throw new Whatever() 会完成这项工作,选择一个合适的异常类型并将其记录在您的方法中。甚至可能只是将 throws InterruptedException 添加到您的方法中。回答'how to do exceptions in java'一个堆栈溢出问题有点宽泛,不过教程很多

很可能您的代码中的任何地方都没有任何 .interrupt() 调用,在这种情况下,catch 块是无关紧要的,它永远不会发生。 throw new RuntimeException("uncaught", e); 完全正确 - 它很简单,它不会删除任何信息,它不会导致编译器问题,例如导致您提出这个问题的问题,并且它清楚地传达给 reader代码正在发生什么(即:您不希望发生此异常,或者如果它确实发生了,也不会费心写任何关于它的具体信息, 您想要消除的麻烦处理来自任何来电者的问题。