有没有一种方法可以抛出一个异常而不添加抛出声明?

我有以下情况。

我有一个 Java 类,它从另一个基类继承并重写一个方法。 基方法不引发异常,因此没有 throws ...声明。

现在我自己的方法应该能够抛出异常,但是我可以选择抛出异常或抛出异常

  • 接受异常或
  • 添加抛出声明

这两种方法都不能令人满意,因为第一种方法会无声地忽略异常(好吧,我可以执行一些日志记录) ,而第二种方法会因为不同的方法头而产生编译器错误。

public class ChildClass extends BaseClass {


@Override
public void SomeMethod() {
throw new Exception("Something went wrong");
}
}
73568 次浏览

You can throw unchecked exceptions without having to declare them if you really want to. Unchecked exceptions extend RuntimeException. Throwables that extend Error are also unchecked, but should only be used for completely un-handleable issues (such as invalid bytecode or out of memory).

As a specific case, Java 8 added UncheckedIOException for wrapping and rethrowing IOException.

Why don't you throw an unchecked exception? This doesn't have to be declared.

Two alternatives are

  • wrap with a checked exception with an unchecked one.
  • don't let the compiler know you are throwing a checked exception e.g. Thread.currentThread().stop(e);
  • In Java 6, you can rethrow the exception if it is final and the compiler know which checked exceptions you might have caught.
  • In Java 7, you can rethrow an exception if it is effectively final, i.e. you don't change it in code.

The later is more useful when you are throwing a check exception in you code and catching it in your calling code, but the layers inbetween don't know anything about the exception.

A third option is to opt out of exception checking (just like the Standard API itself has to do sometimes) and wrap the checked exception in a RuntimeException:

throw new RuntimeException(originalException);

You may want to use a more specific subclass of RuntimeException.

you can catch the exception with try- catch block in your method overridden. then you don't need to declare throws- statement.

Here's an example for intercepting checked exceptions and wrapping them in an unchecked exception:

public void someMethod() {
try {
doEvil();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}

You can use any exception derived from RuntimeException or RuntimeException itself

or

use a try-block for the exception throwing code and handle it there

I just want do add an alternative answer, purely as an FYI:

Yes, there is a way to throw a checked exception without adding the throws declaration, by using the sun.misc.Unsafe class. This is described in the following blog post:

Throw a checked exception from a method without declaring it

Sample code:

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);
}
}

However, this is not recommended. It is better to wrap in an unchecked exception as outlined in the some of the other answers.

Here is a trick:

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!"));
}
}

Yes there is a why but it is not recommended at all you can use :

Java unsafe package

getUnsafe().throwException(new IOException());

This method throws checked exception, but your code not forced to catch or rethrow it. Just like runtime exception.

If you use Project lombok and want to throw checked exceptions without the throws declaration, you can add @SneakyThrows to the method:

public void yourCaller(){
yourMethod();
}
@SneakyThrows
public void yourMethod(){
throw new Exception("Something went wrong");
}


This can throw checked exceptions without the caller needing to catch them.

Lombok provides an annotation processor that modifies the code at compile-time. With @SneakyThrows, it catches and re-throws the exception without the throws declaration.

As described in the description of @SneakyThrows, it transforms code into something like that:

public void yourMethod() {
try {
throw new Exception("Something went wrong");
} catch (Exception t) {
throw Lombok.sneakyThrow(t);
}
}

From the sources of Lombok.sneakyThrow():

public static RuntimeException sneakyThrow(Throwable t) {
if (t == null) throw new NullPointerException("t");
return Lombok.<RuntimeException>sneakyThrow0(t);
}


@SuppressWarnings("unchecked")
private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T {
throw (T)t;
}

As you can see, it uses generics to trick Java into thinking that this would be an unchecked exception as shown in this answer.

In Java 8, throwing a checked exception without declaring it can be done more easily due to type inference.

public class Main {
public static void main(String[] args) {
throwException(new Exception("exception"));
}
    

public static <T extends Throwable> void throwException(Throwable t) throws T {
throw (T) t;
}
}

Yes there is, using typecast to Runtime exception and throws a runtime exception.

Create an Exception helper class like this.

public class ExceptionHelper {
public static  <T> void throwException(Throwable t) throws Throwable {
throw (Throwable) t;
}
}
class ServiceClass {
public void actualFlow() {
try {
//somethinf
} catch (Exception e) {
ExceptionHelper.throwException(e);
}
}
}