封面:洛小汐
译者:潘潘
知彼知己,方能百战不殆。
前言
本文总结了无关Java异样的十大常见问题。
目录
- 查看型异样(checked) vs. 非查看型异样(Unchecked)
- 异样治理的最佳实际箴言
- 为什么在try代码块中申明的变量不能在catch或者finally中被援用?
- 为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异样不一样呢?
- Java中常常应用的运行时异样
- 咱们能够在同一个catch子句中捕捉多个异样吗?
- 在 Java 中构造方法能抛出异样吗?
- 在 final 代码块中抛出异样
- try语句有return那么finally还会执行吗?
- 为何有些开发人员对异样束之高阁?
查看型异样(checked) vs. 非查看型异样(Unchecked)
简略来说,对于查看型异样, 个别在 编译期 就会被查看到,所以咱们必定会提前在办法内进行捕捉解决,或者在办法头部申明并抛出。而非查看型异样,往往无奈提前预知,例如被除数是0、空指针等。查看型异样特地重要,它会通知那些调用你的接口的开发者们,如何提前预知并解决好这些可能产生的异样。
例如,IOException就是常见的查看型异样,而 RuntimeException(运行时异样)就是非查看型异样。在浏览残余局部之前你或者能够研读这份 Java异样的层次结构图。
异样治理的最佳实际箴言
如果能够正确处理异样,则应将其捕捉并解决,否则应将其抛出。
为什么在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代码块中哪个地位会引发异样, 很有可能在申明对象之前就引发了异样。对于这个特定的示例,是正确的。
为什么 Double.parseDouble(null) 和 Integer.parseInt(null) 抛出的异样不一样呢?
它俩抛出的异样的确不同,但这是JDK的问题,过后开发这两个接口的开发人员不是同一波,所以咱们没必要去纠结这个问题。
Integer.parseInt(null); // throws java.lang.NumberFormatException: null Double.parseDouble(null); // throws java.lang.NullPointerException
Java中常常应用的运行时异样
这里列举一部分:
IllegalArgumentException
ArrayIndexOutOfBoundsException
在有些场景某个指标对象不满足咱们的预期,会用到这些异样,例如上面在 if 判断语句中被应用:
if (obj == null) { throw new IllegalArgumentException("obj can not be null");
咱们能够在同一个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 都写上,这也是继承准则。
在 Java 中构造方法能抛出异样吗?
答案是当然能够,构造方法仅是一种非凡办法而已。能够参考这个示例。
在 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(); }}
try语句有return那么finally还会执行吗?
答案是必定会执行。
Java官网文档形容:The finally block always executes when the try block exits
意思就是 ” 只有存在try代码块,finally代码块就肯定会执行 ” ,这种个性能够让程序员防止在try语句中应用return, continue或者break关键字而疏忽了敞开相干资源的操作等。
为何有些开发人员对异样束之高阁?
很多时候会见到上面这种代码写法。容许的状况下尽可能捕捉异样并且进行解决,不晓得为什么很多开发人员就是这么干?
try { ...} catch(Exception e) { e.printStackTrace();}
疏忽异样是一件很容易做到的事,尽管这种写法很常见,但不肯定是正确的写法。
参考文献:
- Unchecked exceptions in Java
- The root of Java exception class hierarchy
- Java exceptions related questions in stackoverflow
译文完,因为集体理解能力和常识宽度无限,译文中存在失误之处,还请见谅,欢送斧正。
BIU ~ 文章继续更新,微信搜寻「潘潘和他的敌人们」第一工夫浏览,随时有惊喜。本文会在 GitHub https://github.com/JavaWorld 收录,热腾腾的技术、框架、面经、解决方案,咱们都会以最美的姿态第一工夫送达,欢送 Star。