java 构造器(constructor)

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

  用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

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

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

相关文章

keeplive linux平台下,Linux下搭建keepalive+nginx

一、 安装nginx(略)二、 安装keepalive安装依赖包 yum install –y popt* gcc* openssl* nmaptar fvxz keepalived-1.2.15.tar.gzcd keepalived-1.2.15./configure –prefix/usr/local/keepalivedmake && make installmkdir /etc/keepalived ##为keepalived创建配置文…

第二十二期:淘宝技术架构分享

一,淘宝技术架构 1.UIC: 用户中心(User Interface Center),提供所有用户信息相关的读写服务,如基本信息,扩展信息,社区信息,买卖家信用等级等等。 淘宝现在有两类卖家B 和C,这是通过在用户身上打不同的标签…

Linux启动过程以及初始化

Linux系统启动 POST加电自检–> 硬件检查 引导加载程序BIOS(Boot Sequence)–> 找到主引导记录(MBR),引导加载程序检查分区表并找到一个可引导的分区 加载对应引导上的MBR(bootloader)–> 引导加载程序将所选操作系统的内核加…

Deep learning with Python 学习笔记(9)

神经网络模型的优化 使用 Keras 回调函数 使用 model.fit()或 model.fit_generator() 在一个大型数据集上启动数十轮的训练,有点类似于扔一架纸飞机,一开始给它一点推力,之后你便再也无法控制其飞行轨迹或着陆点。如果想要避免不好的结果&…

linux c 读取摄像头,Linux下onvif客户端获取ipc摄像头 获取能力:GetCapabilities

getcapabilities:获取能力,主要目的获取设备能力信息(获取媒体服务地址)鉴权:但是在调用获取设备能力之前是需要鉴权的。onvif协议规定,部分接口需要鉴权,部分接口不需要鉴权,在调用需要鉴权的接口时不使用鉴权,会导致…

[计算机网络][HTTP]

定义 超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协 议。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。通过HTTP或者HTTPS协议请求的资源由 统一资…

8次c语言上机作业答案,计算机二级C语言上机题库及答案2017

计算机二级C语言上机题库及答案2017引导语:我们将要迎来2017年9月份的计算机考试,大家准备好了吗,以下是百分网小编分享给大家的计算机二级C语言上机题库及答案2017,欢迎测试!一、填空题给定程序中已建立一个带有头结点的单向链表…

Swagger Learing - Spring Boot 整合swagger

学习了一下swagger。 这是编写的Demo 源码 https://github.com/AmberBar/Learning/tree/master/swagger-learning/swagger 需要的小伙伴可以clone直接运行 访问地址 http://localhost:9999/swagger-ui.html#/ 转载于:https://www.cnblogs.com/amberbar/p/10308256.html

[Leedcode][JAVA][第202题][快乐数]

【问题描述】 编写一个算法来判断一个数 n 是不是快乐数。「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为…

c语言结构体实现存储信息,用C语言结构体实现通讯录

实现一个通讯录;通讯录可以用来存储1000个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址提供方法:1. 添加联系人信息2. 删除指定联系人信息3. 查找指定联系人信息4. 修改指定联系人信息5. 显示所有联系…

Java类加载机制的理解

算上大学,尽管接触Java已经有4年时间并对基本的API算得上熟练应用,但是依旧觉得自己对于Java的特性依然是一知半解。要成为优秀的Java开发人员,需要深入了解Java平台的工作方式,其中类加载机制和JVM字节码这样的核心特性。今天我将…

java学习(171): 枚举类

定义一个枚举类 //枚举类型 public enum test122 {RED,GREEN,BLUE;}测试类 public class test123 {public static void main(String[] args){System.out.println( test122.BLUE );test122[] sigstest122.values();for(test122 e:sigs){System.out.println( "枚举名称&qu…

[剑指offer]面试题第[48]题[Leetcode][JAVA][第3题][无重复字符的最长字串][滑动窗口][HashSet/Map]

【问题描述】[第3题][无重复字符的最长字串] 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。示例 1:输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 示例 2:输入: "bb…

c语言程序改错例题,C语言程序改错习题

C语言程序改错习题行动是通向成功的唯一途径。以下是小编为大家搜索整理的C语言程序改错习题,希望能给大家带来帮助!更多精彩内容请及时关注我们应届毕业生考试网!在考生文件夹下,给定程序MODI.C的功能是:求一维数组a中的.最大元素及其下标。…

java学习(172): 使用class实现反射编程,创建对象

//class反射编程 //定义一个学生类 public class test124 {public String name;protected int age;double height;private double money;public test124(String name,Integer age){this.namename;this.ageage;}public test124(String name,int age,double money){this.namename…

关于mysql中GROUP_CONCAT函数的使用

偶然看到公司存储过程中有个字符串拼接的函数,改bug过程中使用到了,还挺有用的,于是记录下来方便记忆,帮助有需要的人。 这是我需要整理的串,他是调用了一个存储过程,传入组织机构的id和迭代层数&#xff0…

linux中tuned是否启动命令,tuned-adm 性能调优分析

tuned-adm 性能调优分析徐小东 (a.k.a toy)(xxdlhygmail.com)2017.04tuned-adm 简介RHEL 自带的性能调优工具,通过针对特定应用场景提供配置 (profile) 来改善系统性能性能调优方向CPU: governor、energy_perf_bias、min_perf_pct性能调优方向CPU: governor、energy…

java学习(173):class反射编程方法

//class反射编程 //定义一个学生类 public class test124 {public String name;protected int age;double height;private double money;public test124(String name,Integer age){this.namename;this.ageage;}public test124(String name,int age,double money){this.namename…

[剑指offer]面试题第[25]题[Leedcode][JAVA][第21题][合并两个有序链表]

【问题描述】[简单] 将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例:输入:1->2->4, 1->3->4 输出:1->1->2->3->4->4【解答思路】 1. 非递归 时间复杂度&…

Windos下navcat连接虚拟机中的mysql

进入mysql命令行, 使用root用户,密码:youpassword(你的root密码)连接到mysql服务器:  # mysql -u root -proot   mysql>GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIED BY youpassword WITH GRAN…