【问题标题】:Can I prevent java from throwing certain exceptions?我可以防止java抛出某些异常吗?
【发布时间】:2016-04-14 15:52:48
【问题描述】:

我有来自两个不同类的 2 个对象,它们共享一个通用类型的属性(IpAddress 也包含有关子网的所有信息)。现在,IpAddress 是一个用户定义类型,我有一个函数 setSecondaryRouter() 可以改变这种类型的属性。为了使程序按预期运行,我需要一个不变量(或实际上是 2 个不变量)来保持。这在函数setSecondaryRouter() 中进行了检查。但是,我想将此属性 secondaryRouter 在第二个对象中设置为与第一个对象相同。这意味着不变量在我第二次使用setSecondaryRouter() 时已经成立。因此,我知道该函数不会抛出。

问题是我的编译器“帮助”通过不编译来确保我没有未捕获的异常,除非我添加一个 try-catch 子句或在调用函数中添加一个 throws 声明(从而帮助解决一个不存在的问题) .我要做的是告诉Java不会抛出这个异常。将此与 c++ 中的 nothrow 关键字进行比较。我知道已经发布了类似的问题,如下所示

Is there any standard annotation to indicate nothrow semantics in Java?

但我的问题不同,我不想在我知道不会被抛出的特定异常中添加 throw 或 try-catch 子句!

还有一个表达式是 IllegalArgumentException。这个异常可以成为我必须处理异常的原因吗?

【问题讨论】:

  • 让他们检查异常。那么,它没有被方法声明为抛出的事实意味着它没有被方法抛出。
  • @AndyTurner 所以即使我知道必须处理运行时异常?
  • 不。您不必处理未经检查的异常;你只是不能保证它们不会被扔掉。
  • 不,你不能保证它们不会被抛出。

标签: java exception


【解决方案1】:

要回答这个问题,必须区分checked and unchecked exceptions

  • 如果一个方法没有声明它抛出一个检查异常,它不能抛出该类型(或其子类型之一)的异常:

    void doSomething() {
      throw new Exception();  // Illegal, without throws Exception on doSomething();
    }
    

    因此,您知道如果方法未声明抛出该异常,则该方法不会抛出已检查异常。

    已检查的异常旨在被捕获,因为它们假定指示您可以从中恢复的条件,因此您需要知道它们发生了。例如IOException: 如果稍后再试,文件可能存在,磁盘可能有空间,网络可能已备份(等等)。

  • 一个方法可以抛出一个未经检查的异常,而无需声明它确实如此;但同样,如果您不想捕获它,则无需进行任何工作(例如,因为您知道它不可能被抛出)。因此,您永远无法保证某个特定的 RuntimeException 不会被某个方法抛出 - 也许它不是由您调用的方法直接抛出的,但它可能会被一个方法抛出 调用(现在或将来的实现)。

    未经检查的异常并不是真的要被捕获,因为它们应该表示不可恢复的错误,例如编程错误。例如NullPointerException: 你可以用同样的参数调用同样的方法,但还是会失败,因为你运行的是同样的代码。

【讨论】:

  • 啊,好吧,我明白了,这是另一个已检查的异常(未提及,称为InternalException,它的含义无关紧要),这会导致麻烦。所以你的意思是没有办法告诉java 不处理一个已检查的异常,因为我知道这是之前处理的?回答这个问题,我会接受(意味着我会为我不使用的东西付费......)。
  • 没错。您总是必须通过捕获或传播检查的异常来处理它。
【解决方案2】:

java.lang.IllegalArgumentException 是运行时异常,因此编译器不会考虑它。

如果第一次使用setSecondaryRouter() 可能引发异常,则必须声明它。

也许你可以声明一个新方法cloneFirstRouterToSecondRouter,类似于跟随,捕捉你的异常。

    public void cloneFirstRouterToSecondRouter(){
      try{
         setSecondaryRouter();
      catch(Exception e){
         // should never occur
      }
    }

【讨论】:

  • 请注意,“不应该发生”的情况的代码路径应该总是做一些事情以防万一,例如throw new AssertionError(e);,所以你知道quite how "never" they occur in practice
  • :( 好吧,我明白了,这很烦人。我想 Java 中不存在“这是你自己的错”。大哥 oracle 强制我们做正确的事情,即使我们知道“错误的事情会永远不会发生”,从而执行性能惩罚。无论如何感谢您的建议
【解决方案3】:

阻止方法抛出异常是不可能的。这是因为JVM可能会导致一个方法throw a VirtualMachineError at anytime。特别是,一个方法可能会抛出一个OutOfMemoryError 即使它本身不直接或间接分配内存(使用new 运算符)。这不仅仅是理论上的问题:如果垃圾收集线程花费的时间过长,一些并发垃圾收集器会这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2018-12-23
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多