- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
谁能解释一下这段代码吗?
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,它允许抛出已检查的异常而不声明它们。
<小时/>我知道这与类型删除有关,但我不确定是否理解黑客攻击的每个部分。
<小时/>编辑:我知道我们可以插入 Integer
在 List<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/
谁能解释一下这段代码吗? public class SneakyThrow { public static void sneakyThrow(Throwable ex) { SneakyT
我对@SneakyThrows 可用于偷偷抛出已检查的异常有疑问,而无需在您的方法的 throws 子句中实际声明它。 public class Demo { public static vo
谁能解释一下这段代码? public class SneakyThrow { public static void sneakyThrow(Throwable ex) { SneakyTh
我正在使用 @SneakyThrows Lombok我的 SpringBoot 中的功能项目。 当 CGLIB 代理实现时,我遇到了这个功能的问题 它抛出 java.lang.Exception:意外
我是一名优秀的程序员,十分优秀!