有一点很重要,即你要时刻询问子句"如果异常发生了,所有东西能被正确清理码?",尽管大多数情况下时非常安全的,但涉及到构造器时,问题出现了,构造器会把对象设置成安全的初始状态,但还会又别的动作,比如打开一个文件,这样的动作只有在对象使用完毕并且用户调用了特殊的清理方法之后才能得以清理,如果在构造器内抛出了异常,这些行为也许就不能正常工作了,这意味着在编写构造器时要格外细心.

用finally也许可以解决问起,但问题并非如此简单,因为finally会每次都执行清理操作,如果构造器在执行过程中半途而废,也许该对象的某部分还没有创建成功就要被清理,这又会抛出新的异常(.close()也会抛出异常)

1.构造器抛出异常要格外注意清理方法是否有必要调用,如果方法恰当,直接向上层抛出的确能简化编程

package exceptions;
//: exceptions/InputFile.java
// Paying attention to exceptions in constructors.
import java.io.*;public class InputFile {private BufferedReader in;public InputFile(String fname) throws Exception {try {in = new BufferedReader(new FileReader(fname));// Other code that might throw exceptions} catch(FileNotFoundException e) {System.out.println("Could not open " + fname);// Wasn't open, so don't close it //如果没有打开文件就不需要关闭throw e;} catch(Exception e) {// All other exceptions must close it  如果时其它异常则必须关闭文件try { //in.close()也可能抛出异常,所有要放到try块里面in.close();} catch(IOException e2) {System.out.println("in.close() unsuccessful");}throw e; // Rethrow} finally {  //由于finally总会被执行,如果在这里关闭文件则文件刚打开还没开始使用就关闭了// Don't close it here!!!
    }}public String getLine() {String s;try {s = in.readLine();} catch(IOException e) { //这这异常已被捕获,因此getLine不会抛出任何异常throw new RuntimeException("readLine() failed");//重新抛出新的异常到上层环境,有时会简化编程}return s;}public void dispose() {try {in.close();System.out.println("dispose() successful");} catch(IOException e2) {throw new RuntimeException("in.close() failed");}}
} ///:~

2.对于在构造器阶段可能抛出的异常,并且要求清理的,最安全的使用方法时使用嵌套的try子句,

package exceptions;
//: exceptions/Cleanup.java
// Guaranteeing proper cleanup of a resource.public class Cleanup {public static void main(String[] args) {try {InputFile in = new InputFile("Cleanup.java");try {String s;int i = 1;while((s = in.getLine()) != null); // Perform line-by-line processing here...} catch(Exception e) {//这里捕捉的时getLine()方法重新抛出的异常System.out.println("Caught Exception in main");e.printStackTrace(System.out);} finally { //如果构造成功,则一定会执行in.dispose()清理
        in.dispose();}} catch(Exception e) { //InputFile对象在自己的try语句块优先,因此构造失败会进入这里,而不会执行内部的try块的in.colse()System.out.println("InputFile construction failed");}}
} /* Output:
dispose() successful
*///:~

3. 这种通用的清理惯用法在构造器不跑出任何异常时也应该应用,其基本规则时:在需要清理的对象之后,立即进入一个try-finally语句块.

//基本上,你应该仔细考虑所有的可能细节,例如本例的dispose()如果可以抛出异常,那么就需要额外的try语句块package exceptions;
//: exceptions/CleanupIdiom.java
// Each disposable object must be followed by a try-finallyclass NeedsCleanup { // Construction can't failprivate static long counter = 1;private final long id = counter++;public void dispose() {System.out.println("NeedsCleanup " + id + " disposed");}
}class ConstructionException extends Exception {}class NeedsCleanup2 extends NeedsCleanup {// Construction can fail:public NeedsCleanup2() throws ConstructionException {}
}public class CleanupIdiom {public static void main(String[] args) {// Section 1:NeedsCleanup nc1 = new NeedsCleanup();try {// ...} finally {nc1.dispose();}// Section 2:// If construction cannot fail you can group objects:// nc5 constructor 如果对象构造不能失败就不需要任何catch//不能失败的对象构造器对象可以群众在一起NeedsCleanup nc2 = new NeedsCleanup();NeedsCleanup nc3 = new NeedsCleanup();try {// ...} finally {nc3.dispose(); // Reverse order of construction
      nc2.dispose();}// Section 3:// If construction can fail you must guard each one:try {NeedsCleanup2 nc4 = new NeedsCleanup2();try {NeedsCleanup2 nc5 = new NeedsCleanup2();try { //如果nc5对象构造失败则会调用try块清理,否则永不调用// ...} finally {nc5.dispose();}} catch(ConstructionException e) { System.out.println(e);} finally {nc4.dispose();}} catch(ConstructionException e) { // nc4 constructor
      System.out.println(e);}}
} /* Output:
NeedsCleanup 1 disposed
NeedsCleanup 3 disposed
NeedsCleanup 2 disposed
NeedsCleanup 5 disposed
NeedsCleanup 4 disposed
*///:~

转载于:https://www.cnblogs.com/jiangfeilong/p/10303179.html

java 构造器(constructor)相关推荐

  1. java 构造器 构造方法_Java构造器(构造方法/constructor)

    我们先来看一下什么是构造器: 1.构造器也叫构造方法或构造函数,分为有参构造器和无参构造器: 2.构造器也是一种方法,只不过是一种特殊的方法,它会在对象创建的时候被调用: 3.构造器最大的作用就是在创 ...

  2. java构造器_Java构造器就是这么简单!

    前言 理解构造器之前,首先我们需要了解Java中为什么要引入构造器,以及构造器的作用. 在很久之前,程序员们编写C程序总会忘记初始化变量(这真的是一件琐碎但必须的事),C++引入了 构造器(const ...

  3. java占位符打印_什么是 Java 构造器?

    构造器是编程的强大组件.使用它们来释放 Java 的全部潜力. -- Seth Kenlon(作者) 在开源.跨平台编程领域,Java 无疑(?)是无可争议的重量级语言.尽管有许多 伟大的跨平台 框架 ...

  4. 子类构造器Constructor是否可被Override(重写)

    构造器Constructor不能被继承,因此不能被重写(Override),但是可以被重载(Overload) 如果父类自定义了有参构造函数,则子类无论定义构造函数与否,定义有参构造函数与否,都会报错 ...

  5. java的constructor怎么用,constructor函数 Java中的构造函数Constructor怎么用

    Java中的构造函数Constructor怎么用 注意: 由于Java不允许像C++那样为函数的参数提供缺省值,因此在构造函数中也不能使用缺省值. 构造函数的特点: 1.它的函数名与类名相同: 2.它 ...

  6. java构造器详解_Java中关于构造器的使用详解

    这篇文章主要介绍了Java构造器使用方法及注意事项的相关资料,这里举例说明如何使用构造器及需要注意的地方,需要的朋友可以参考下 Java构造器使用方法及注意事项 超类的构造器在子类的构造器运行之前运行 ...

  7. Java反射 Constructor类

    Java反射 Constructor类 Java通过反射可以获取构造方法,和使用构造方法创造对象. 在网上找了一个比较好理解的例子来弄清楚Constructor类. public Constructo ...

  8. 用Java构造器来计算圆的周长和面积

    用Java构造器来计算圆的周长和面积 提供测试线束 •我们可以为任何类声明main方法. •这对于单独测试类很有用在把它集成到一个更大的程序之前. •Java只运行类的main方法: 以Java这个词 ...

  9. Java构造器(构造方法)

    Java构造器(构造方法)详解 什么是构造器 构造器通常也叫构造方法.构造函数,构造器在每个项目中几乎无处不在.当你new一个对象时,就会调用构造器.构造器格式如下: [修饰符,比如public] 类 ...

最新文章

  1. iOS macOS的后渗透利用工具:EggShell
  2. NSA释出逆向工程工具GHIDRA针对恶意软件逆向分析
  3. NYOJ 士兵杀敌(二) 树状数组
  4. java-servlet
  5. linux 命令tf,Linux文件管理命令
  6. mysql时区代码_mysql时区设置为东八区
  7. 科大讯飞 开放平台 开发者 语音识别
  8. 高等计算机教材系列·多媒体技术教程,高等学校计算机规划教材:多媒体技术应用教程...
  9. 如何将文件PDF格式转换成Word格式
  10. 【FXCG】海龟交易法的使用方法和注意事项
  11. 青海省海西蒙古族藏族自治州谷歌高清卫星地图下载
  12. 经典点云配准算法:迭代最近点算法ICP(Iterative Closest Point)
  13. MATLAB实现混淆矩阵
  14. scrapy 动态网页处理——爬取鼠绘海贼王最新漫画
  15. Flutter技术与实战(6)
  16. SSH工具连接虚拟机
  17. Java期末考试试题及参考答案(04)
  18. SpiderFlow平台v0.3.0初次使用并爬取薄荷网的热量和减法功效
  19. 东软,内部员工离职述说
  20. 如何制作一个类似Tiny Wings的游戏(2) Cocos2d-x 2.1.4内含iOS版源代码

热门文章

  1. slide简介(大数据技术)
  2. Linux epoll的用法
  3. [机器学习笔记]Note8--机器学习应用建议
  4. ssh登录服务器提示错误no hostkey alg
  5. Tomcat 配置 login 和 gas
  6. hadoop 2.7.2 + zookeeper 高可用集群部署
  7. modelsim 安装后运行,出现fatal License Error
  8. 关于HbSrv.exe
  9. 计算机专硕专业课单科分数线,计算机考研|这两所自划线,单科没过线也能复试?...
  10. Netty入门篇-从双向通信开始