- 浏览: 51932 次
- 性别:
- 来自: 湘潭
-
文章分类
最新评论
-
yuxingfirst:
Mon__cherie 写道无意中发现一个bug当数组中有两个 ...
算法研究系列---快速排序 -
Mon__cherie:
无意中发现一个bug
当数组中有两个一样的数字事 whi ...
算法研究系列---快速排序 -
fka2004:
学习了,谢谢~~
算法研究系列---快速排序 -
yuxingfirst:
自己先占个坐,由于小弟水平有限,有不对的地方,请各位指正... ...
对java的一些总结<一> -
yuxingfirst:
补充:上面程序中的“//是在给maze分配内存的时候有点点问题 ...
自己写的链栈实现的迷宫算法,发帖纪念下...
有时候我们可能会问:“当异常发生的时候,所有的东西都会被正确的清除吗?”,大多数情况下是相当安全的,不过在涉及到构造方法的时候问题就出现了。通常,构造器会把对象设置成安全的初始状态,但是它也可能会执行某些操作,比如,打开一个在使用完对象以及调用特定的清理方法之前不需要进行垃圾清理的文件。如果实在构造器了抛出异常,那么这么垃圾清理方法可能不会被正确执行,这就意味着在写你的构造方法的时候你必须十分用心。
也许你会把 finally 作为一种解决方案,但事实并不如此简单,应为finally在每次进行清理时都会执行一次。试想,如果一个构造器在它执行的过程中失败了,这样,这个对象的某些成员它并 没有成功创建,然而,在finally子句中这些部分也是要被清理的,这就是一个缺陷。
如下面这个例子:
package chapter12; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; 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(); } catch (IOException e2) { System.out.println("in.close()unsuccessful"); } throw e; // Rethrow } finally { // Don’t close it here!!! } } public String getLine() { String s; try { s = in.readLine(); } catch (IOException e) { 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"); } } }这个类很简单,也很容易理解。如果在InputFile的构造方法里抛出了FileNotFoundException,则说明文件没有被成功打开,因而,in这个BufferedReader的对象实例没有成功创建,此时如果在finally里面这样写 in.close(),这就是不合理的。所以在构造方法抛出FileNotFoundException时,我们并不需要调用in.close()对象,因为它没有关联到一个具体的文件上;不过当抛出其他Excpetion时,我们就需要关闭文件了,因为这时指定的文件已成功打开。另外需要说明的是dispose方法,这个方法是你在使用完InputFile对象之后需要调用的,它用来释放系统资源(例如文件句柄)。可能你会想到把这个功能放到finalize方法里面,然而我们知道我们无法确定finalize方法是否总是会被调用,即便会被调用我们也无法确定会在什么时候调用。从这里就牵扯出java语言的一个缺陷,在java里面只有内存的清理是自动执行的,除此之外其他的一切都不会自动清除,所以我们要通知客户端程序员dispose方法是有一定的职责的。
在构造方法可能抛出异常的情况下,比较安全的做法是使用嵌套的try,比如下面所演示的:
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) { System.out.println("Caught Exception in main"); e.printStackTrace(System.out); } finally { in.dispose(); } } catch (Exception e) { System.out.println("InputFile construction failed"); } } }这个程序的逻辑不难分析。InputFile构造器内部的try块是可以生效的,当在构造方法里产生了异常,则会进入上面例子中外部的try块的catch子句,这是不用执行dispose方法;不过要是InputFile对象实例成功被构造,那么在内部的try块里就必须要执行dispose方法。按照上面程序段的写法就可以保证:只要InputFile的对象被成功创建,那么一定会执行dispose方法,释放系统资源。
对于构造方法可能会抛出异常的情况,通用的习惯用法是:在需要进行清理的对象被创建后,立即接上try-finally块,如下面的代码所示:
package chapter12; class NeedsCleanup { // Construction can’t fail private 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: 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 { // ... } finally { nc5.dispose(); } } catch (ConstructionException e) { // nc5 constructor System.out.println(e); } finally { nc4.dispose(); } } catch (ConstructionException e) { // nc4 constructor System.out.println(e); } } }按照这种写法,可以看出:对于那些构造方法不会产生异常的类,我们总能对它进行清理;对于构造方法有可能产生异常的类,我们总能在必要时对它进行清理。
发表评论
-
Lucene02----整体架构
2011-12-02 13:57 836Lucene的总体架构 Lucene ... -
Lucene02----整体架构
2011-11-30 13:36 5Lucene的总体架构 Lucene ... -
Lucene01----全文索引
2011-11-30 13:29 924一:全文检索 在文本检索里,全文索引是一种搜索单 ... -
Java HashMap分析
2011-11-29 13:07 1040基于哈希表 ... -
stack heap
2011-10-19 00:00 786一、预备知识—程序的内存分配 一个由C/C++编译的程 ... -
关于IntegerCache的理解
2011-10-17 16:51 2388今天在javaeye上看到一兄弟贴的代码, ... -
记录2
2011-10-11 22:47 7线程池的原理: ... -
记录1
2011-10-11 22:41 10链表、树、线程安全、 ... -
面试题汇总
2011-10-11 22:35 10/////////////////////////////// ... -
算法研究系列---二叉查找树
2011-10-10 17:48 933查找树以便于查找的方式来存放数据,尤其是二叉查找树,二叉查找树 ... -
谈谈对于企业级系统架构的理解
2011-05-30 00:49 719在我们刚开始学习架构的时候,首先会想到分层的概念,分层架构 ... -
字符集和整理
2011-03-27 16:07 1009整理 描述 armscii8 (ARMSCI ... -
页面静态化方案
2011-03-08 22:13 843在大型网站中,访问者看到的页面基本上是静态页面。为什么都要 ... -
ASCII
2011-03-01 08:23 875ASCII表 ASCII值 控制字符 A ... -
解决方案:Tomcat启动时窗口一闪而过(startup.bat)
2011-02-22 22:23 3379有时候我们在apache网站上下载了tomcat的zip包后, ... -
String ,StringBuilder,StringBuffer的区别
2011-02-17 16:18 812String类代表字符串,java ... -
Java 技术新手入门
2011-01-11 21:31 814Java 技术是什么? ... -
数组的初始化
2011-01-10 13:27 945就我自己而言,一般在 ... -
深入Java 2 SDK
2011-01-05 16:46 0大家都知道,每一个初学java的人在开始学习java之前必做的 ... -
apache 前任竹席的言语
2010-12-22 08:47 834(说明:文章的“竹 ...
相关推荐
- **“析构方法”Finalize**:虽然不建议使用`finalize()`方法,但在某些情况下,如处理稀缺资源,可能仍需考虑资源的优雅释放。不过,更推荐使用诸如`try-with-resources`语句或显式关闭资源的方式来进行资源管理。...
鉴于此,本篇文章将介绍一种创新的水利工程闸口处的垃圾自动清理装置及其制作方法,该装置通过巧妙的设计,有效解决了上述问题。 首先,装置的结构设计是该自动清理装置的核心。装置主要由支撑板、支撑架和垃圾收集...
此时,需要合理处理这些异常情况,向用户提供友好的错误提示。 6. **设置和选项**:为了提高用户体验,垃圾文件清理工具应允许用户自定义清理规则,如设置排除目录、选择清理级别等。这可以通过对话框或选项卡界面...
这三种方法各有优势,AHP便于处理复杂问题,但可能受到主观判断影响;模糊综合评价法适用于模糊条件,但需要处理不确定性;GIS则能直观呈现空间信息,但依赖于数据质量和分析技巧。综合运用这些方法,能够提高垃圾...
在这种情况下,匿名对象仅用于调用`run()`方法,之后就会变成垃圾,等待垃圾回收器清理。 封装是面向对象的三大特性之一,它隐藏了对象的实现细节,只对外暴露必要的接口。封装的主要目的是提高代码的安全性,减少...
本文将详细讨论一种创新的环保节能垃圾焚烧处理设备的制作方法,该设备旨在提升垃圾处理的效率和彻底性,同时解决传统设备在处理含水垃圾和大型垃圾方面的不足。 该环保节能垃圾焚烧处理设备的核心构造包括底座、...
本文深入探讨了C++与C#这两种编程语言中异常处理机制的核心概念,特别是如何在这些机制中处理对象的构造与析构问题,同时分析了在异常处理过程中如何有效地管理内存资源。 #### 关键词 C++, C#, 异常处理, 公共...
综上所述,基于支持向量机理论的垃圾邮件过滤模型,尤其是结合模糊支持向量机的方法,能够在处理邮件的模糊性和非对称性方面表现出色,有助于提高邮件过滤的准确性和效率。未来的研究方向可以进一步探索如何更有效地...
城市垃圾运输问题是一个复杂的城市规划问题,涉及到交通优化、资源分配和环境管理等多个方面。...这种方法不仅有助于解决当前的问题,也为其他类似的实际问题提供了解决思路,如物流配送、货物运输等。
由于C++没有内置的垃圾回收机制,程序员需要手动管理内存,这可能导致内存泄漏、悬空指针等问题。然而,C++通过提供构造函数和析构函数,以及一些智能指针的设计,如`std::shared_ptr`和`std::unique_ptr`,来帮助...
传统的建筑垃圾处理方法存在分类不彻底、人工干预多等问题。为了解决这些问题,本文介绍了一种新型建筑垃圾分类设备的制作方法,该设备的设计理念和工作原理能够在分类精度和效率上取得突破,为实现建筑垃圾的资源化...
2.2 建筑垃圾产生情况:明确指出垃圾总量(约4000方)和类型(建筑垃圾、弃料、余泥、废弃物),并提出了消纳方式(密闭式车辆外运)及具体要求,如定期清理、避免乱倒乱卸,保持场地整洁,减少运输过程中的扬尘问题...
在使用__del__()时,也需要注意循环引用的问题,这可能导致内存泄漏,因为循环引用的对象永远不会被垃圾回收。 在实际应用中,开发者应当尽量避免在__del__()中执行复杂的操作,因为这可能导致程序的不稳定性。例如...
- 特点: 如果一个方法可能抛出此类异常,要么在方法签名中通过`throws`关键字声明抛出,要么在方法体内通过`try-catch`结构处理。 - 处理方式: 必须通过声明或捕获的方式来处理,否则编译失败。 #### 三、Java...
永登县生活垃圾处理场建设工程的岩土工程勘察报告是一份详细评估了该工程建设场地地质状况的重要文件。报告的目的是为了确保垃圾处理场的安全、稳定和环保运营,为设计和施工提供科学依据。以下是对报告中关键知识点...
在某些情况下,我们可能希望控制对象的创建方式,这时可以使用工厂方法。工厂方法是一种特殊的静态方法,负责创建和返回类的实例。它可以提供更灵活的实例化逻辑,比如条件判断、对象缓存等。 六、构造函数和析构...
在全球范围内,厨余垃圾与餐厨垃圾的处理问题日益严峻,不仅影响城市的公共卫生,还可能对环境造成严重污染。面对这一挑战,合理有效的厨余垃圾、餐厨垃圾堆肥系统设计方案显得尤为重要,它不仅能够将废弃物转化为对...
随着城市化进程的加速,生活垃圾的产生量急剧增加,随之而来的垃圾填埋处理也产生了大量的垃圾渗滤液。垃圾渗滤液是垃圾填埋过程中因雨水或地下水渗透所形成的高浓度有机废水,它不仅气味难闻,还含有多种有毒有害...
而且,为了保证在移动过程中垃圾桶的稳定性,特别配有的脚踏开关和脚刹设计,允许使用者在不直接接触垃圾桶的情况下,轻松开启和固定垃圾桶,从而大大减少了操作风险和意外事故发生的概率。 针对实验室废液的处理,...