gpt4 book ai didi

Java SneakyThrow 异常、类型删除

转载 作者:行者123 更新时间:2023-12-02 00:13:36 25 4
gpt4 key购买 nike

谁能解释一下这段代码吗?

public class SneakyThrow {


public static void sneakyThrow(Throwable ex) {
SneakyThrow.<RuntimeException>sneakyThrowInner(ex);
}

private static <T extends Throwable> T sneakyThrowInner(Throwable ex) throws T {
throw (T) ex;
}



public static void main(String[] args) {
SneakyThrow.sneakyThrow(new Exception());
}


}

这可能看起来很奇怪,但这不会产生强制转换异常,并且允许抛出已检查的异常,而无需在签名中声明它,或者将其包装在未检查的异常中。

请注意, sneakyThrow(...) 都没有或者主要声明任何已检查的异常,但输出是:

Exception in thread "main" java.lang.Exception
at com.xxx.SneakyThrow.main(SneakyThrow.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

这个 hack 在 Lombok 中使用,带有注释 @SneakyThrow,它允许抛出已检查的异常而不声明它们。

<小时/>

我知道这与类型删除有关,但我不确定是否理解黑客攻击的每个部分。

<小时/>

编辑:我知道我们可以插入 IntegerList<String>检查/未检查异常的区别是编译时功能。

当从非泛型类型(如List)进行转换时为通用类型,如 List<XXX>编译器会产生警告。但直接转换为泛型类型(如 (T) ex)的情况并不常见。在上面的代码中。

如果你愿意的话,对我来说奇怪的部分是,我知道在 JVM 内部有 List<Dog>List<Cat>看起来是一样的,但是上面的代码似乎意味着我们最终也可以将 Cat 类型的值赋给 Dog 类型的变量或者类似的东西。

最佳答案

如果您使用 -Xlint 编译它,您将收到警告:

c:\Users\Jon\Test>javac -Xlint SneakyThrow.java
SneakyThrow.java:9: warning: [unchecked] unchecked cast
throw (T) ex;
^
required: T
found: Throwable
where T is a type-variable:
T extends Throwable declared in method <T>sneakyThrowInner(Throwable)
1 warning

这基本上是说“这个转换在执行时真正没有被检查”(由于类型删除) - 所以编译器不情愿地假设你正在做正确的事情,因为知道它不会'实际上并没有被检查。

现在只有编译器关心已检查和未检查的异常 - 它根本不是 JVM 的一部分。所以一旦你通过了编译器,你就可以回家了。

不过,我强烈建议您避免这样做。

在许多情况下,当您使用泛型时,会进行“真正的”检查,因为某些东西使用了所需的类型 - 但情况并非总是如此。例如:

List<String> strings = new ArrayList<String>();
List raw = strings;
raw.add(new Object()); // Haha! I've put a non-String in a List<String>!
Object x = strings.get(0); // This doesn't need a cast, so no exception...

关于Java SneakyThrow 异常、类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61069309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com