使用Unsafe.getUnsafe().throwException抛出异常

dog*_*ane 8 java unsafe exception

我在java.lang.Class #newInstance0中遇到了一些有趣的代码:

// Run constructor
try {
    return tmpConstructor.newInstance((Object[])null);
} catch (InvocationTargetException e) {
    Unsafe.getUnsafe().throwException(e.getTargetException());
    // Not reached
    return null;
}
Run Code Online (Sandbox Code Playgroud)

查看Unsafe.getUnsafe().throwException声明.它看起来像是从一个没有声明它被抛出的方法抛出一个已检查的异常!

他们为什么这么做?
如果Sun开发人员可以使用这种技术,我们也可以这样做吗?

Luk*_*der 5

使用 Java 和泛型,您可以从类型擦除中受益,并且只需使用以下简单技巧抛出任何异常:

public class Test {
    public static void main(String[] args) {
        doThrow(new SQLException());
    }

    public static void doThrow(Exception e) {
        Test.<RuntimeException> doThrow0(e);
    }

    @SuppressWarnings("unchecked")
    public static <E extends Exception> void doThrow0(Exception e) throws E {
        throw (E) e;
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然有点吓人...


Ste*_*n C 3

他们为什么这么做?

我不完全确定,但我希望有一个很好的理由。(当你深入各个层时,反射调用涉及到一些极其棘手的事情......)

如果Sun开发人员可以使用这种技术,我们也可以这样做吗?

我会说不......除非你有一个非常非常充分的理由。抛出已检查异常而不声明它们的方法违反了最小意外原则。想象一下那个可怜的家伙,他可能必须在凌晨 3 点在关键生产系统中调试您的代码。

只是因为 Sun 的一些工程师认为某件事在特定环境下是一个好主意,但并不一定意味着它在一般情况下是一个好主意。