java各种的不好_译文《最常见的10种Java异常问题》

封面:洛小汐

译者:潘潘

3792064f07696d2020d8dde92054cc49.png

c41654e9fb8cfd3bf36f1c7e029825af.png

知彼知己,方能百战不殆。

19a59106b760a2893b0f43fb9b19d7b9.png

前言

本文总结了有关Java异常的十大常见问题。

目录

检查型异常(checked) vs. 非检查型异常(Unchecked)

异常管理的最佳实践箴言

为什么在try代码块中声明的变量不能在catch或者finally中被引用?

为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异常不一样呢?

Java中经常使用的运行时异常

我们可以在同一个catch子句中捕获多个异常吗?

在 Java 中构造方法能抛出异常吗?

在 final 代码块中抛出异常

try语句有return那么finally还会执行吗?

为何有些开发人员对异常置之不理?

8acdcb1bb1f020fd96b9cdecc164953c.png

检查型异常(checked) vs. 非检查型异常(Unchecked)

简单来说,对于检查型异常, 一般在 编译期 就会被检查到,所以我们肯定会提前在方法内进行捕获处理,或者在方法头部申明并抛出。而非检查型异常,往往无法提前预知,例如被除数是0、空指针等。检查型异常特别重要,它会告诉那些调用你的接口的开发者们,如何提前预知并处理好这些可能发生的异常。

例如,IOException就是常见的检查型异常,而 RuntimeException(运行时异常)就是非检查型异常。在阅读剩余部分之前你或许可以研读这份 Java异常的层次结构图。

825a9eda5e62d59c0f0202e973b9bd00.png

ad1665f97d21445097a723c5b72075ee.png

异常管理的最佳实践箴言

如果可以正确处理异常,则应将其捕获并处理,否则应将其抛出。

af92139fbcae43f0642a7386f1351f55.png

为什么在try代码块中声明的变量不能在catch或者finally中被引用?

看下面这段代码,在try代码块中声明的 String s 就不能在catch中被引用, 这段代码在编译期是通不过的。

try {

File file = new File("path");

FileInputStream fis = new FileInputStream(file);

String s = "inside";

} catch (FileNotFoundException e) {

e.printStackTrace();

System.out.println(s);

}

原因是你不知道在try代码块中哪个位置会引发异常, 很有可能在声明对象之前就引发了异常。对于这个特定的示例,是正确的。

ebbe5f716563a9be33985f9c8e88c2d8.png

为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异常不一样呢?

它俩抛出的异常确实不同,但这是JDK的问题,当时开发这两个接口的开发人员不是同一波,所以我们没必要去纠结这个问题。

Integer.parseInt(null);

// throws java.lang.NumberFormatException: null

Double.parseDouble(null);

// throws java.lang.NullPointerException

585e43951f4ea3916e18dce98a785726.png

Java中经常使用的运行时异常

这里列举一部分:

IllegalArgumentException

ArrayIndexOutOfBoundsException

在有些场景某个目标对象不满足我们的预期,会用到这些异常,例如下面在 if 判断语句中被使用:

if (obj == null) {

throw new IllegalArgumentException("obj can not be null");

ac25348c2a6859253c62902d7b0e9bff.png

我们可以在同一个catch子句中捕获多个异常吗?

答案是当然可以,不过如果在同一个catch子句中捕获的这些异常都直接或间接继承自同一父类,那么就只能在catch子句中捕获父类了。

// Java 7 之前需要这样

catch (AException a) {

logger.error(a);

throw new MyException("a");

catch (BException b) {

logger.error(b);

throw new MyException("b");

}catch (CException c) {

logger.error(c);

throw new MyException("c");

}

// 在Java 7中,可以捕获所有这些异常

catch(AException | BException | CException ex){

logger.error(ex);

throw new MyException(ex);

}

补充说明 : 其实是这样,在 Java7 就开始支持catch子句捕获多个异常,多个异常使用 XOR符号(I)连接,异常的发生有可能是 A | B,但不能同时出现,相当于这些异常不能是间接或直接继承自同一个父类,因为如果AB都继承同一父类,那就不能 A|B 都写上,这也是继承原则。

ee6467dc2c4ffc00f708c557a62cbaf3.png

在 Java 中构造方法能抛出异常吗?

答案是当然可以,构造方法仅是一种特殊方法而已。可以参考这个示例。

ca2fb8e86366ae7203b8a85142468cc9.png

在 final 代码块中抛出异常

下面这个写法是合法的:

public static void main(String[] args) {

File file1 = new File("path1");

File file2 = new File("path2");

try {

FileInputStream fis = new FileInputStream(file1);

} catch (FileNotFoundException e) {

e.printStackTrace();

} finally {

try {

FileInputStream fis = new FileInputStream(file2);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

}

}

但是为了获得更好的代码可读性,你应该将把 try-catch代码块封装成一个新方法,然后将方法调用放在finally子句中:

public static void main(String[] args) {

File file1 = new File("path1");

File file2 = new File("path2");

try {

FileInputStream fis = new FileInputStream(file1);

} catch (FileNotFoundException e) {

e.printStackTrace();

} finally {

// 封装方法

methodThrowException();

}

}

e46efdea7b97d8606d9b783a79fa331a.png

try语句有return那么finally还会执行吗?

答案是肯定会执行。

Java官方文档描述:The finally block always executes when the try block exits

意思就是 ” 只要存在try代码块,finally代码块就一定会执行 ” ,这种特性可以让程序员避免在try语句中使用return, continue或者break关键字而忽略了关闭相关资源的操作等。

dbbe7900eb14de50bd21fb23a97fead6.png

为何有些开发人员对异常置之不理?

很多时候会见到下面这种代码写法。允许的情况下尽可能捕获异常并且进行处理,不知道为什么很多开发人员就是这么干?

try {

...

} catch(Exception e) {

e.printStackTrace();

}

忽略异常是一件很容易做到的事,虽然这种写法很常见,但不一定是正确的写法。

参考文献:

译文完,由于个人理解能力和知识宽度有限,译文中存在失误之处,还请见谅,欢迎指正。

2b4b80530063459a3f4eb0f8f998615c.png

a869a7de2df4000346c1f9d0a75ff7d9.png

BIU ~ 文章持续更新,微信搜索「潘潘和他的朋友们」第一时间阅读,随时有惊喜。本文会在 GitHub https://github.com/JavaWorld 收录,热腾腾的技术、框架、面经、解决方案,我们都会以最美的姿势第一时间送达,欢迎 Star。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop 开源调度系统zeus(二)

紧跟之前Hadoop 开源调度系统zeus(一) 本节主要介绍一下zeus的架构: 先给一个zeus的架构图 无论Master还是Worker都有一套WEB UI,无论从哪个上面去看,看到的结果都是一样的,实际上一般仅仅看主 Master:调度内核&#x…

ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER

该宏非常重要, 其作用是: 创建一个渲染命令任务,并将该任务压入渲染队列,待渲染线程执行. 主要用于多线程渲染!#define ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(TypeName,ParamType1,ParamName1,ParamValue1,Code…

python十条建议_十条建议帮你提高Python编程效率

程序员的时间很宝贵,Python这门语言虽然足够简单、优雅,但并不是说你使用Python编程,效率就一定会高。要想节省时间、提高效率,还是需要注意很多地方的。今天就与大家分享资深Python程序员总结的10点建议,帮助大家大幅…

Django:快速搭建简单的Blog

一,创建项目 1, 为blog创建名为mysite的工程项目: django-admin.py startproject mysite2, 项目结构如下: mysite├── manage.py└── mysite├── __init__.py├── settings.py├── urls.py└── wsgi.pymanage.py ----- Django项目…

添加纹理到材质

1. 导入一个图片资源作为纹理贴图 2. 新建一个材质 3. 打开材质编辑器,将“TextureSample”和“TextureCoordinate”两个材质表达式放到蓝图中 4. 设置“TextureSample”的纹理属性为第1步导入的纹理贴图 5. 将“TextureCoordinate”的输出与“TextureSample”的UVs…

c# 路径空格---ProcessStartInfo参数问题

今天在整合程序的时候,要从一个程序转到另一个程序 当然要使用: ProcessStartInfo startInfo new ProcessStartInfo("\\Program Files\\IE\\IE.exe", s); Process.Start(startInfo); 不过对于wm来说 不支持Process.St…

发票 ocr java_OCR识别技术—增值税发票识别

增值税发票识别产品背景在经济活动中产生大量的增值税发票需要进行扫描、数据录入、人工校对等工作。传统的人工录入方式,用户需要投入大量的人力成本和时间成本,不仅抬高了运营成本,而且录入速度难以提升,错误率难以降低&#xf…

java se好用吗_利用 Java SE 7 更好地管理资源

2011 年 5 月发布作者:Julien Ponge本文介绍 Java 7 针对自动资源管理问题给出的解决办法,即 Coin 项目中提出的新语言结构 try-with-resources 语句。:示例源文件 (zip) 简介典型的 Java 应用程序可以处理多种类型的资源,如文件、…

法线贴图Nomal mapping 原理

法线贴图多用在CG动画的渲染以及游戏画面的制作上,将具有高细节的模型通过映射烘焙出法线贴图,贴在低端模型的法线贴图通道上,使之拥有法线贴图的渲染效果,却可以大大降低渲染时需要的面数和计算内容,从而达到优化动画…

Html.Action、html.ActionLink与Url.Action的区别

1.html.ActionLink返回的指向指定controller、指定action的超链接标签<a>标签.如果没有指定controller&#xff0c;则默认为本页面对应的Controller. 如Html.ActionLink(“链接文本”、“someaction”、“somecontroller”,new { id " 123 " },null)生成:<…

ss

http://blog.csdn.net/lvanneo/article/details/16885121 http://www.360doc.com/content/11/0506/22/6110614_114908124.shtml转载于:https://www.cnblogs.com/mliudong/p/3851502.html

gdi+ 双缓冲

内存bmp方式 1. 初始化 Gdiplus::Bitmap* pBitmap new Gdiplus::Bitmap(w,h); Gdiplus::Graphics* pGraphics Gdiplus::Graphics::FromImage(pBitmap); pGraphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality); pGraphics->SetInterpolationMode(Gdiplus::In…

Javascript引擎单线程机制及setTimeout执行原理说明

setTimeout用法在实际项目中还是会时常遇到。比如浏览器会聪明的等到一个函数堆栈结束后才改变DOM&#xff0c;如果再这个函数堆栈中把页面背景先从白色设为红色&#xff0c;再设回白色&#xff0c;那么浏览器会认为DOM没有发生任何改变而忽略这两句话&#xff0c;因此我们可以…

java实现c语言的函数_C语言实现返回字符串函数的四种方法

前言C语言返回字符串函数共有四种方式&#xff0c;分别如下&#xff1a;使用堆空间&#xff0c;返回申请的堆地址&#xff0c;注意释放函数参数传递指针&#xff0c;返回该指针返回函数内定义的静态变量(共享)返回全局变量下面来看看详细的介绍其实就是要返回一个有效的指针&am…

解决VS命令提示符 “Setting environment for using Microsoft Visual Studio. 此时不应有“系列错误

一、起因 最近在玩Boost库。当然首先是要进行Boost库的安装和配置。于是浅墨Google了一下boost库的安装配置攻略&#xff0c;下载了最新版1.55的boost库&#xff0c;就愉悦地开始进行配置了。 当进行到第五步&#xff0c;要在VS命令提示符中运行bootstrap.bat的时候&#xff0c…

yii2多语言设置

yii2的多语言切换功能 1.页面添加语言切换按钮&#xff0c;如下图&#xff1a; 代码如下&#xff1a; <ul> <li> <a href"javascript:;" οnclick"changeLanguage(en_US);"> <span><?php echo …

php 字符串 大括号,PHP中的字符串大括号

复杂(卷曲)语法这并不是因为语法复杂&#xff0c;而是因为它允许使用复杂表达式。任何具有字符串表示的标量变量、数组元素或对象属性都可以通过此语法包括在内。只需将表达式以与字符串外显示的方式相同的方式写入&#xff0c;然后将其包装在{和}..自{无法转义&#xff0c;只有…

bat

1. 打印变量 set a 123echo %a%2. if errorlevel 测试前一程序的返回状态。如果该程序的返回状态大与或等于所说明的值就执行所说明的DOS命令 if errorlevel 命令让批处理文件测试一程序的返回状态值&#xff0c;然后根据测试结果作相应的进一步处理&#xff0c;当MS-DOS遇到…

APP安全环节缺失,手游运营商怎样应对APP破解困境

2013年手游行业的规模与收入均实现了大幅增长&#xff0c;发展势头强劲。然而&#xff0c;在手游快速发展的同一时候&#xff0c;因为监管、审核等方面存在着漏洞&#xff0c;手机游戏软件被破解后注入恶意代码、盗取用户財产、窃取用户设备信息的现象屡见不鲜。手游被破解后黑…

UE4版本和vs版本的对应关系

查找UEBuildWindows.cs文件&#xff0c;里面记录了此版本的UE4可以用哪个版本的VS编译 比如 4.19.1版本 public enum WindowsCompiler {/// <summary>/// Use the default compiler. A specific value will always be used outside of configuration classes./// </su…