gpt4 book ai didi

Java SneakyThrow of exceptions,类型删除

转载 作者:IT老高 更新时间:2023-10-28 20:52:24 30 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,它允许在不声明的情况下抛出已检查的异常。


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


编辑:我知道我们可以插入 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

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

现在只有 编译器 关心已检查和未检查的异常——它根本不是 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 of exceptions,类型删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14038649/

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