《Head First Java》读书笔记(3) - 异常和IO

1、异常处理

我们在调用某个方法时,会被编译器告知需要捕捉异常和处理,意味着你调用的这个方法是有风险的,可能会在运行期间出状况,你必须写出在发生状况时加以处理的代码,未雨绸缪!这就是Java中异常处理机制的意义。

异常处理看似和直接使用if else的方式雷同,实际上if else必须嵌入到正常业务逻辑代码中去,逻辑代码和业务代码混杂,而异常将它们独立开来,主次明确,可读性高。

下面两段代码,可以感受一下。

  1. FileReader fr = new FileReader("path");
  2. if (fr == null) {
  3. System.err.println("Open File Error");
  4. } else {
  5. BufferedReader br = new BufferedReader(fr);
  6. while (br.ready()) {
  7. String line = br.readLine();
  8. if (line == null) {
  9. System.err.println("Read Line Error");
  10. } else {
  11. System.out.println(line);
  12. }
  13. }
  14. }
  1. try {
  2. FileReader fr = new FileReader("path");
  3. BufferedReader br = new BufferedReader(fr);
  4. while (br.ready()) {
  5. String line = br.readLine();
  6. System.out.println(line);
  7. }
  8. } catch (IOException e) {
  9. e.printStackTrace();
  10. }

异常分为运行期异常和编译期异常(也称为checked exception 检测异常),实际上编译器不会管运行期的异常的,如数学异常,空指针异常等,它不会要求我们进行try catch,为什么?

在这里还要提一下throws,也就是异常链的概念,我们说捕捉到一个异常,如果不当场处理的话,可以往上抛,让调用者来进行捕获。

假设有一段代码,可能抛出空指针异常,如果你当前代码不进行异常处理,throws的意思即是说,你必须告诉上面的人,我有可能有这个毛病,但是我没改,你自己看着办吧。

假如某代码要求传参必须是正数,负数则抛出异常,但自身不处理,而是throws。那么对于调用者来说,第一调用者知道了我现在正在使用的这段代码它有一定的范围限制,因为编译器告诉我了我必须要抓异常,否则可能会出错;第二调用者可以未雨绸缪来处理这种可能发生的状况。

2、序列化和IO

2.1 写在前面的延伸

突然想到了字符集的相关概念,这里就再提出来温习一下最基本的。

我们知道,对于计算机而言,它仅认识两个0和1,我们所看到的文字、图片、视频等等“数据”在计算机中都是二进制形式存在的。不同字符对应二进制数的规则,就是字符的编码。字符编码的集合称为字符集。

每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000000到11111111。

2.2 序列化

一般来说,串流要两两连接才能做出有意义的事情,其中A表示连接,B则是要被调用方法的。为什么要两个?因为连接的串流A是很低级的,以FileOutputStream为例,它是可以写入字节的,但是我们通常不会直接写字节,而是以对象层次的观点来写入,所以还需要高级的连接串流B。

再形象一点,序列化时发生的事情大概是这样:

对象中如果存储的是基本数据类型,那么序列化时很简单,但是如果对象还有其他对象的引用呢?实际上,对象序列化时,被该对象引用的对象也会被序列化。另外,序列化是全有或者全无的,不会出现只序列化一部分的情况,要么完全成功,要么彻底失败。

我们知道,某个我们希望序列化的对象,我们可以让它实现一个标记接口Serializable,但是如果在这个类中有某个变量我们不希望它随着对象一起序列化,那么就把变量标记为transient(瞬时),这样序列化程序就会跳过它。

而至于反向序列化:

注意,可能存在这样的问题,假如我们想把Dog对象还原带回来,而此时某个transient变量已经从double改成了String,很显然,这会伤害到序列化的兼容性。

使用serialVersionUID进行版本控制:

(1)每当对象被序列化的同时,该对象都会被“盖”上一个类的版本识别ID,即serialVersionUID。如果在对象被序列化之后,类有了不同的ID,则还原操作会失败

(2)如果你认为类有可能会演化,则把版本是别ID放在类中

2.3 IO操作

File类,代表磁盘上的文件,但是并不表示文件上的内容,准确地说,你可以想象成文件的路径,而不是文件本身。

File类是IO输入的基本类,这里简单提一下,不详细展开了,下面说我们所谓的缓冲区:



使用缓冲区比没有使用的效率更高,实际上你确实可以直接使用FileWriter,调用write()来写文件,就像如上你在超市购物,你每拿一样东西就跑去收银台付一次账,如果没有像超市推车一样的缓冲区,你确实可以达到最终目的,但是也累得不行,效率还低。

而我们常说的flush(),实际上就是强制缓冲区立即写入,形象地说,就是马上把推车推到收银台去结一次账。

时间: 2024-10-16 15:41:23

《Head First Java》读书笔记(3) - 异常和IO的相关文章

Effective Java 读书笔记之八 异常

一.只针对异常的情况才使用异常 1.类具有状态相关的方法时,可采用状态测试方法和可识别的返回值两个策略. 二.对可恢复的情况使用受检异常,对编程错误使用运行时异常 1.期望调用者能够适当恢复的情况,应该使用受检的异常. 2.用运行时异常来表明编程错误. 三.编码不必要地使用受检异常 1.使用受检异常的两个条件: a.正确地使用API并不能阻止这种异常条件的发生 b.异常发生后,使用API的程序员可以立即采取有用的动作. 四.优先使用标准的异常 1.IllegalArgumentException

【java读书笔记】——java的异常处理

程序在实际环境的运行过程中,安全成为需要首先考虑的重要因素之一,这也是用户和程序员最关心的问题.同时,Java语言健壮性也体现在了能够及时有效地处理程序中的错误,准确的说是Java的异常处理机制为解决安全问题提交了一份满意的答卷. 先从整体上看一下本文要介绍的内容,然后进行详细的分析: 1.异常的概念 异常又称为例外,是特殊的运行错误对象,对应着Java语言特定的运行错误处理机制. 上面的概念是书本上说的,下面我谈一下自己的看法 其实异常处理机制提供了统一的机制来识别和响应程序错误,异常可以为我

【java读书笔记】JSTL,快速精通

JSTL并不是什么新颖的技术而且很简单,甚至有人认为JSTL已经过时了.但是我认为它既然存在,就有存在的道理,作为技术人员就应该知道它们是什么,怎么使用,有什么优点. JSTL包含两部分:标签库和EL语言.下面先介绍标签库,再介绍EL语言,最后总结一下JSTL的优点. JSTL JSTL简介 JSTL(JavaServer Page Standard Tag Library,即:JSP标准标签库),是由SUN公司提供的简化JSP页面设计的标签.JSTL是由Core(核心库).Format(格式化

think in java 读书笔记

java中没有单独函数的概念,依赖类的方法. java中优化了向前引用,类可以在调用者之后. java中包的命名方法实际上是网址的倒转. c++中因为存在全局变量和函数所以会存在一个变量名冲突的问题,但是java中不存在全局变量,不同程序设计者通过不同的类将相同名字的变量和方法隔离. static关键字 通常,我们创建类时会指出那个类的对象的外观与行为.除非用new 创建那个类的一个对象,否则实际上并 未得到任何东西.只有执行了new 后,才会正式生成数据存储空间,并可使用相应的方法. 但在两种

Effective Java 读书笔记(2创建和销毁对象)

第一章是引言,所以这里不做笔记,总结一下书中第一章的主要内容是向我们解释了这本书所做的事情:指导Java程序员如何编写出清晰.正确.可用.健壮.灵活和可维护的程序. 2.1考虑用静态工厂方法代替构造器 静态工厂方法与构造器相比有四大优势: (1)静态工厂方法有名称,具有适当名称的静态工厂方法易于使用.易于阅读: (2)不必每次在调用它们的时候都创建一个新的对象: (3)可以返回原返回类型的任何子类型的对象: (4)在创建参数化类型实例的时候,它们使代码变得更加简洁. 同时静态工厂方法也有两大缺点

Effective Java读书笔记(4 类和接口)

4.1 使类和成员的可访问性最小化 要区别设计良好的模块和设计不好的模块,最重要的因素在于,这个模块对于外部的其他模块而言,是否隐藏其内部数据和其他实现细节.设计良好的模块会隐藏所有的实现细节,把它的API与它的实现清晰的隔离开来,然后模块之间只通过API进行通信,一个模块不需要知道其他模块内部的工作情况,这个概念被称为信息隐藏或封装,是软件设计的基本原则之一. 4.2 在公有类中使用访问方法而非公有域 坚持面向对象程序设计思想:如果类可以在它所在的包的外部进行访问,就提供访问方法,以保留将来改

Effective Java读书笔记(3对于所有对象都通用的方法)

3.1 覆盖equals时请遵守通用约定 什么时候应该覆盖Object.equals()方法呢? 如果类具有自己特有的"逻辑相等"概念(不同于对象等同的概念),而且超类还没有覆盖equals以实现期望的行为,这时我们就需要覆盖equals方法. Object.equals()方法具有自反性.对称性.传递性.一致性和与null比较返回false的特点. 实现高质量equals方法的诀窍: (1)使用==操作符检查"参数是否为这个对象的引用".如果是,则返回true,这

think in java 读书笔记 3 —— 数据报

目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 概要 1. 数据报基本知识 1. 数据报基本知识 之前套接字中例子使用的都是“传输控制协议”(TCP),亦称作“基于数据流的套接字”.根据该协议的设计宗旨,它具有高度的可靠性,而且能保证数据顺利抵达目的地.换言之,它允许重传那些由于各种原因半路“走失”的数据.而且收到字节的顺序与它们发出来时是一样的.当然,这种控制与可靠性需要我们付出一些代价:TCP 具有非常高的开销. 还有另一种协

【java读书笔记】——java开篇宏观把控 + HelloWorld

学完java有一段时间了,一直没有做相应的总结,总觉得有一种缺憾.从这篇博客开始,将自己平时的学习笔记进行总结归纳,分享给大家. 这篇博客主要简单的介绍一下java的基础知识,主要的目的是扫盲.原来只是听说过java,现在自己真正开始学习了,看完了第一集视频之后,问自己,你知道java是什么吗?问完之后才发现一无所知,上完查一查,简单了解一下,给自己扫盲. 介绍 知道java是一种可跨平台应用软件的面向对象的程序设计语言,就可以了. 组成 Java由四方面组成:java编程语言,java类文件格

think in java 读书笔记 1 ——移位

在Think in Java中有这么一段话“对char,byte或者short进行移位处理,那么在移位进行之前,它们会自动转换成一个int.只有右侧的5个低位才会有用.这样可防止我们在一个int数里移动不切实际的位数.若对一个long值进行处理,最后得到的结果也是long.此时只会用到右侧的6个低位,防止移动超过long值里现成的位数.” 对上面那段话的理解是:移位操作符操作的运算对象是二进制的“位”,int类型是32位也就是2的5次幂 !如果移32位以上,那么原来的数的信息会全部丢失,这样也就