【问题标题】:Return only if no Exception is thrown仅在没有抛出异常时返回
【发布时间】:2015-09-30 00:23:23
【问题描述】:

我在 java 中实现了一个固定大小的 Queue,它使用一个恒定大小的 ArrayList 作为底层容器,我的 front() 方法应该返回 Queue 的前端元素。

   public T front(){


        try{
            if(isEmpty())
                throw new Exception("Queue is Empty- can't return Front element.");
            return arrayList.get(frontIndex);

        }catch (Exception e){
            System.out.println(e);
        }

    }

通过上述方式编码,我希望 front() 只有在没有抛出异常的情况下才返回一个值,但是正如预期的编译器向我显示“缺少返回语句。 "那么,有什么方法可以让函数只有在没有抛出异常的情况下才返回。

【问题讨论】:

  • 如果方法具有非void 返回类型,您必须返回一个值,或抛出异常。没有其他选择。你想对这两个选项做什么?

标签: java exception-handling return


【解决方案1】:

如果您事后捕获异常,为什么还要使用它?您必须返回 T 或抛出异常。但是该方法不会抛出异常,因为您正在捕获它。这样做不是更容易吗:

   public T front() throws SomeException{ // if SomeException is checked you need to declare it
        if(isEmpty())
            throw new SomeException("Queue is Empty- can't return Front element.");
        return arrayList.get(frontIndex);
    }

您还应该使用更具体的异常,而不是异常。

【讨论】:

  • 异常是为了被捕获他应该抛出一个错误
  • 异常可以被捕获,但通常是被方法的调用者捕获,而不是在方法本身中
  • 异常与错误的区别是什么?永远不应该发现错误
  • @TomaszBest ,嗯,异常是处理异常情况的机制,不会让程序突然终止,所以不是错误,抛出异常适合我的问题。
  • @user140547 ,您能否说明为什么通常不会在生成异常的方法中捕获异常?
【解决方案2】:

由于您在代码中捕获异常,编译器会显示缺少返回语句错误。

你可以像这样实现函数:

public T front() throws Exception {

    if(isEmpty()) {
       throw new Exception("Queue is Empty- can't return Front element.");
    }

    return arrayList.get(frontIndex);
}

最后在调用函数/客户端时处理异常

【讨论】:

    【解决方案3】:

    我希望 front() 只有在没有抛出异常时才返回一个值

    反问:如果抛出异常,您想要返回什么?

    这就是问题所在。您已将 front() 声明为返回某些内容(T 的一个实例)。这意味着有两种相关方式1可以终止对front()的调用:

    • 它可以通过返回符合T类型的东西来正常终止。

    • 它可以通过抛出未经检查的异常来异常终止。

    你不能返回“nothing”,因为front()必须返回一个值。

    您不能抛出已检查异常(如 Exception),因为 front() 未声明为抛出任何异常。


    那你能做什么?

    • 您可以更改方法签名,以便抛出SomeException,其中SomeExceptionException 下降。 (投掷Exception 是一个非常糟糕的主意......)

    • 您可以将throw new Exception 更改为throw new SomeException,其中SomeExceptionRuntimeException 的后代。

    • 假设T 是引用类型,您可以返回null。 (如果T 是类型参数,则为。)


    1 - 实际上,还有其他几种方法,但它们在这种情况下没有用。例如,您可以调用 System.exit(int) 并终止 JVM。 (并且有一些结构化代码的方法,这样您就不需要在 exit 调用之后使用(冗余)returnthrow。提示:不需要返回无限循环。)

    【讨论】:

    • 即使你调用System.exit(int)你仍然需要返回一个值或者抛出一个异常;编译器不知道调用System.exit(int) 后程序流停止。
    • 修辞我可以返回任何 T 类型或 null ,即使会抛出异常
    • 谢谢,你的反问让我明白了,我很感激!
    • @TomaszBest - 你错过了对“想要”这个词的强调。这就是我想要表达的观点。
    • @stephen-c 我在您的解释中看不到第三种可能性:1)抛出 ex,2)返回对象 T 类型或 null 3)抛出 ex 并返回 T 类型对象或 null 见我回答我的意思
    【解决方案4】:

    这个“例子”展示了你可以抛出异常并返回值

    的可能性
    private boolean throwExReturnValue() throws NullPointerException {
    
        try {
    
           throw new NullPointerException("HAHA");
        }
    
        finally {
    
            return true;
        }
    }
    
    private void ExceptionHanler() {
    
         boolean  myEx; 
    
         try { 
    
           myEx = throwExReturnValue(); 
    
           /** code here will still execute & myEx will have value = true */
    
         } catch (Exception ex) {
    
           /** will execute or not (depending on VM) even we throwed an exception */
    
         }
    
        /** code will still execute */
    
    }
    

    编辑:

    我用两个不同的 VM 尝试过这个,令我惊讶的是一个是抛出异常,第二个是跳过 catch 块并执行代码,所以它取决于 VM 的实现

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 2020-01-19
      • 2010-09-08
      • 2012-12-22
      • 2012-06-08
      相关资源
      最近更新 更多