有没有办法在不添加throws声明的情况下抛出异常?

Jür*_*ock 71 java exception-handling

我有以下情况.

我有一个Java类,它继承自另一个基类并覆盖一个方法.基本方法不会抛出异常,因此没有throws ...声明.

现在我自己的方法应该能够抛出异常,但我要么选择了

  • 吞下例外
  • 添加投掷声明

两者都不满意,因为第一个会默默地忽略异常(好吧我可以执行一些日志记录)而第二个会因为方法标题不同而产生编译器错误.

public class ChildClass extends BaseClass {

        @Override 
        public void SomeMethod() {
            throw new Exception("Something went wrong");
        }
}
Run Code Online (Sandbox Code Playgroud)

Sto*_*ica 90

如果你真的想要,你可以抛出未经检查的异常,而不必声明它们.未经检查的异常会延长RuntimeException.扩展的Throwables Error也未经检查,但只应用于非常严重的问题(例如无效的字节码).

作为一个特例,Java 8添加UncheckedIOException了包装和重新抛出IOException.


Eng*_*uad 38

这是一个技巧:

class Utils
{
    @SuppressWarnings("unchecked")
    private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T
    {
        throw (T) exception;
    }

    public static void throwException(Throwable exception)
    {
        Utils.<RuntimeException>throwException(exception, null);
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Utils.throwException(new Exception("This is an exception!"));
    }
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*rdt 27

第三种选择是选择退出异常检查(就像标准API本身有时必须做的那样)并将检查的异常包装在RuntimeException:

throw new RuntimeException(originalException);
Run Code Online (Sandbox Code Playgroud)

您可能想要使用更具体的子类RuntimeException.


dog*_*ane 9

我只想添加一个替代答案,纯粹作为一个FYI:

是的,throws通过使用sun.misc.Unsafe类,有一种方法可以在不添加声明的情况下抛出已检查的异常.这在以下博客文章中描述:

从方法中抛出已检查的异常而不声明它

示例代码:

public void someMethod() {
  //throw a checked exception without adding a "throws"
  getUnsafe().throwException(new IOException());
}

private Unsafe getUnsafe() {
  try {
    Field field = Unsafe.class.getDeclaredField("theUnsafe");
    field.setAccessible(true);
    return (Unsafe) field.get(null);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,不建议这样做.如某些其他答案中所述,最好包装未经检查的异常.

  • 他们称之为"不安全"类是有原因的. (3认同)

Pet*_*rey 5

为什么不抛出未经检查的异常?这不必声明。

两种选择是

  • 将已检查的异常与未检查的异常包装在一起。
  • 不要让编译器知道您正在抛出检查异常,例如 Thread.currentThread().stop(e);
  • 在 Java 6 中,您可以重新抛出异常(如果有)final并且编译器知道您可能捕获了哪些已检查异常。
  • 在 Java 7 中,如果异常实际上是最终的,您可以重新抛出异常,即您不在代码中更改它。

当您在代码中引发检查异常并在调用代码中捕获它,但中间的层不知道有关异常的任何信息时,后者更有用。