java 抛异常 jvm_邪恶的Java技巧使JVM忘记检查异常
java 抛异常 jvm
我长期以来一直在批评Java中编译器检查异常的机制。 无论您是爱还是恨,都可以肯定一件事:在某些情况下,您不想与他们打交道。 Java中的解决方案是将一个检查后的异常包装在new RuntimeException(e)
但这可以提供较长的堆栈跟踪,而无需添加有用的信息。 有时,我们只想告诉编译器冷静。
事实证明,通过对Java泛型的类型擦除错误功能的某些不当使用,这是有可能的。 实际操作对理解Java的内部运作方式具有指导意义。 我们走吧!
这是我们想要的:
public static void main(String[] args) {businessLogic();}private static void businessLogic() {List<String> configuration = readConfigurationFile();System.out.println(configuration.get(0));}private static List<String> readConfigurationFile() {try {return Files.readAllLines(Paths.get("non", "existing", "file"));} catch (IOException e) {throw softenException(e);}}
注意, businessLogic()
既不捕获IOException
也不声明它throws IOException
。 相反, softenException()
方法将删除异常的检查。 运行它时,我们得到以下堆栈跟踪:
Exception in thread "main" java.nio.file.NoSuchFileException: non\existing\fileat sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)at java.nio.file.Files.newByteChannel(Files.java:361)at java.nio.file.Files.newByteChannel(Files.java:407)at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384)at java.nio.file.Files.newInputStream(Files.java:152)at java.nio.file.Files.newBufferedReader(Files.java:2784)at java.nio.file.Files.readAllLines(Files.java:3202)at java.nio.file.Files.readAllLines(Files.java:3242)at insanejava.SoftenExceptionsDemo.readConfigurationFile(SoftenExceptionsDemo.java:21)at insanejava.SoftenExceptionsDemo.businessLogic(SoftenExceptionsDemo.java:15)at insanejava.SoftenExceptionsDemo.main(SoftenExceptionsDemo.java:11)
! 在main方法中引发的异常是NoSuchFileException
,它是IOException
的子类–已检查的异常! 怎么可能? 为什么程序中的任何方法都不必声明throws IOException
?
这是窍门:
private static RuntimeException softenException(Exception e) {return checkednessRemover(e);}private static <T extends Exception> T checkednessRemover(Exception e) throws T {throw (T) e;}
checkednessRemover
方法使用了一个技巧,可以揭示有关Java内部工作的一些信息。 首先,将通用类型参数T绑定到RuntimeException
,以实现softenException
。 这意味着表达式throws T
变成throws RuntimeException
,编译器将其解释为好像没有抛出异常。
但是语句throw (T)e;
理论上应该评估为throw (RuntimeException)e;
。 由于e是NoSuchFileException
,因此您希望此语句导致ClassCastException
。 但是,泛型在Java中的工作方式是,编译器会删除类型信息。 因此,字节码改为throw (Exception)e;
,这很好。
因此,这个奇怪的技巧表明Java编译器从编译的代码中删除了通用信息,而检查的异常纯粹是编译器的功能。 没有检查异常的运行时验证。
我会建议在生产代码中使用此技巧吗? 我不知道。 这很奇怪,可能没什么用,但是当我感到邪恶时,我会自己使用它。 如果没有别的,我希望学习可以让您对Java的内部运作有一些见解。
免责声明 :(1)我在其他地方读到了这个技巧,但是我再也找不到源了。 我以为这是Heinz Kabutz出色的Java专家 通讯,但我找不到源。 (2)这在 Lombok项目中 也实现为
@SneakyThrows
。 如果您使用的是Lombok,则在任何情况下都不应重新实现此博客中的技巧。 请改用@SneakyThrows
。
翻译自: https://www.javacodegeeks.com/2018/05/a-wicked-java-trick-to-make-the-jvm-forget-to-check-exceptions.html
java 抛异常 jvm
java 抛异常 jvm_邪恶的Java技巧使JVM忘记检查异常相关推荐
- 邪恶的Java技巧使JVM忘记检查异常
我长期以来一直批评Java中的编译器检查异常机制. 无论您是爱还是恨,都可以肯定一件事:在某些情况下,您不想与他们打交道. Java中的解决方案是将一个检查过的异常包装在new RuntimeExce ...
- Java面试准备(一)——Java基础
Java基础 一.基础概念与常识 1. Java和C++对比 2. Java语言有哪些特点 3. 什么是字节码?采用字节码的好处? 4. JVM,JRE和JDK 5. Oracle JDK和OpenJ ...
- Java相关课程系列笔记之一Java学习笔记
目 录 一. Java技术基础 1 1.1编程语言 1 1.2 Java的特点 1 1.3 Java开发环境 1 1.4 Java开发环境配置 2 1.5 Linux命令与相关知识 2 1.6 Ecl ...
- JAVA面试题2021最新整理——JAVA基础篇
点赞.收藏不迷路,转载请注明出处,感谢各位! 目录 8种基本数据类型 自动拆装箱 String static关键字 final关键字 continue.break.return区别 面向对象的三大特征 ...
- java异常处理简介_【自学java】异常处理简介
第四章 异常处理 学习 java .刷算法题时,很少有人会在乎异常处理, 要不 try catch . 要不就 throw .但在做项目时候, 异常处理混乱会导致程序可维护性降低.异常本身也是程序的一 ...
- java抛出自定义异常_10 个深恶痛绝的 Java 异常。。
异常是 Java 程序中经常遇到的问题,我想每一个 Java 程序员都讨厌异常,一 个异常就是一个 BUG,就要花很多时间来定位异常问题. 什么是异常及异常的分类请看这篇文章:一张图搞清楚 Java ...
- java 抛异常给上级_java异常处理机制(示例代码)
Exception 类的层次 java中所有的异常类是从 java.lang.Exception 类继承的子类. 而Exception 类是 Throwable (可抛出的)类的子类.除了Except ...
- java抛出数组格式异常,Java中异常
一.异常的概述 在Java中,把异常信息封装成了一个类.当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置.原因等). 二.异常的继承体系和错误的区别 1.异常的继承体系 Thr ...
- 抛出运行时异常的目的_「JAVA」运行时异常、编译时异常、自定义异常,通过案例实践转译和异常链...
Java基础之异常处理机制 什么是异常 从事Java开发的小伙伴对于"异常"应该不陌生,因为每天都会遇到不少异常,或捕获,或抛出.那究竟什么是异常?异常即非正常的,不同于平常.一般 ...
最新文章
- 微信小程序web-view使用
- wifi动不动就断开_手机信号满格,但是WIFI经常掉线!我来教你怎么办
- 程序员常用的六大技术博客类
- Python 图像处理篇-利用opencv库展示本地图片实例演示
- Sleep()和wait()方法的区别
- python用户界面导入图片_python学习笔记之11:图像用户界面
- AOP 中必须明白的概念-通知(Advice)
- 在 SAP conversation AI 里消费 ABAP OData 服务
- 为什么苹果内购总是失败_IOS用户支付失败 购买无法完成解决教程
- HTML5项目笔记8:使用HTML5 的跨域通信机制进行数据同步
- 10分钟学会写一个简单的Mysql存储过程
- 电商项目数据库设计 | 第五篇:参考京东商城详细讲解商品数据库设计
- IOS开发之-人脸识别
- excel表格横向纵向变换_Excel新手最容易给自己挖的几个坑,手把手教你完美避雷!...
- 苹果6换屏多钱_iPhone12系列屏幕维修价格公布 苹果12换屏多少钱
- Eclipse创建java web工程
- mysql语句总结_mysql语句总结
- [python] 基于Gradio可视化部署机器学习应用
- [培训-DSP快速入门-3]:C54x DSP内存资源与内存空间分布
- JavaScript中getElementsByName
热门文章
- [学习笔记] 单位根反演
- 【CF1100F】 Ivan and Burgers (分治+线性基)
- P4457-[BJOI2018]治疗之雨【期望dp,高斯消元】
- CF297E-Mystic Carvings【树状数组】
- 2021牛客暑期多校训练营2 B-Cannon(组合+推式子)
- AIsing Programming Contest 2020 总结
- 学习分享会(2019.5.31)
- 【图论】【最短路】【SPFA】【USACO题库】2.4.4 Bessie Come Home回家(jzoj 1274)
- 永远不要在 MySQL 中使用 UTF-8
- 通俗理解决策树算法中信息增益的