目录

异常处理

1.定义

2.常见的异常

3.如何处理

4.异常的分类

5.Throwable

6.自定义异常

输入输出流(I/O)

1.文件对象

2.什么是流

3.字节流

4.关闭流的方式

5.字符流

6.编码/中文问题

7.缓存流

8.数据流

9.对象流

10.System.in

11.流关系图


异常处理

1.定义

异常:导致程序的正常流程被中断的事件,叫做异常

比如要打开d盘的LOL.exe文件,这个文件是有可能不存在的 
Java中通过 new FileInputStream(f) 试图打开某文件,就有可能抛出文件不存在异常FileNotFoundException 
如果不处理该异常,就会有编译错误 

2.常见的异常

NullPointerException 空指针异常

ArithmeticException 除数为零

ClassCastException 类型转换异常

OutOfIndexException 数组下标越界异常

ParseException 解析异常,日期字符串转换为日期对象的时候,有可能抛出的异常

OutOfMemoryError 内存不足

3.如何处理

异常处理常见手段: try catch finally throws

  • try catch

1.将可能抛出FileNotFoundException 文件不存在异常的代码放在try里
2.如果文件存在,就会顺序往下执行,并且不执行catch块中的代码
3. 如果文件不存在,try 里的代码会立即终止,程序流程会运行到对应的catch块中
4. e.printStackTrace(); 会打印出方法的调用痕迹,如此例,会打印出异常开始于TestException的第16行,这样就便于定位和分析到底哪里出了异常

注:FileNotFoundException是Exception的子类,使用Exception也可以catch住FileNotFoundException

  • 多异常捕捉方法1

有的时候一段代码会抛出多种异常,比如

new FileInputStream(f);

Date d = sdf.parse("2016-06-03");

这段代码,会抛出 文件不存在异常 FileNotFoundException 和 解析异常ParseException 
解决办法之一是分别进行catch

  • 多异常捕捉方法2

另一个种办法是把多个异常,放在一个catch里统一捕捉 

catch (FileNotFoundException | ParseException e) {

这种方式从 JDK7开始支持,好处是捕捉的代码更紧凑,不足之处是,一旦发生异常,不能确定到底是哪种异常,需要通过instanceof 判断具体的异常类型

  • finally

无论是否出现异常,finally中的代码都会被执行

  • throws

考虑如下情况:
主方法调用method1,method1调用method2,method2中打开文件

method2中需要进行异常处理,但是method2不打算处理,而是把这个异常通过throws抛出去
那么method1就会接到该异常。 处理办法也是两种,要么是try catch处理掉,要么也是抛出去。
method1选择本地try catch住 一旦try catch住了,就相当于把这个异常消化掉了,主方法在调用method1的时候,就不需要进行异常处理了

  • throw和throws的区别

throws与throw这两个关键字接近,不过意义不一样,有如下区别:
1. throws 出现在方法声明上,而throw通常都出现在方法体内。
2. throws 表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某个异常对象。

4.异常的分类

异常分类: 可查异常,运行时异常和错误3种

  • 可查异常

可查异常: CheckedException
可查异常即必须进行处理的异常,要么try catch住,要么往外抛,谁调用,谁处理,比如 FileNotFoundException
如果不处理,编译器,就不让你通过

  • 运行时异常

运行时异常RuntimeException指: 不是必须进行try catch的异常 
常见运行时异常: 
   除数不能为0异常:ArithmeticException 
   下标越界异常:ArrayIndexOutOfBoundsException 
   空指针异常:NullPointerException 
在编写代码的时候,依然可以使用try catch throws进行处理,与可查异常不同之处在于,即便不进行try catch,也不会有编译错误 
Java之所以会设计运行时异常的原因之一,是因为下标越界,空指针这些运行时异常太过于普遍,如果都需要进行捕捉,代码的可读性就会变得很糟糕。

  • 错误

错误Error,指的是系统级别的异常,通常是内存用光了
在默认设置下,一般java程序启动的时候,最大可以使用16m的内存
如例不停的给StringBuffer追加字符,很快就把内存使用光了。抛出OutOfMemoryError
与运行时异常一样,错误也是不要求强制捕捉的

5.Throwable

Throwable是类,Exception和Error都继承了该类
所以在捕捉的时候,也可以使用Throwable进行捕捉
如图: 异常分Error和Exception,Exception里又分运行时异常和可查异常。

6.自定义异常

  • 创建自定义异常

一个英雄攻击另一个英雄的时候,如果发现另一个英雄已经挂了,就会抛出EnemyHeroIsDeadException
创建一个类EnemyHeroIsDeadException,并继承Exception
提供两个构造方法
1. 无参的构造方法
2. 带参的构造方法,并调用父类的对应的构造方法

  • 抛出自定义异常

在Hero的attack方法中,当发现敌方英雄的血量为0的时候,抛出该异常
   1. 创建一个EnemyHeroIsDeadException实例
   2. 通过throw 抛出该异常
   3. 当前方法通过 throws 抛出该异常

在外部调用attack方法的时候,就需要进行捕捉,并且捕捉的时候,可以通过e.getMessage() 获取当时出错的具体原因

输入输出流(I/O)

1.文件对象

文件和文件夹都是用File代表

  • 创建一个文件对象

使用绝对路径或者相对路径创建File对象

  • 文件常用方法1

注意1: 需要在D:\LOLFolder确实存在一个LOL.exe,才可以看到对应的文件长度、修改时间等信息
注意2: renameTo方法用于对物理文件名称进行修改,但是并不会修改File对象的name属性。

  • 文件常用方法2

2.什么是流

什么是流(Stream),流就是一系列的数据

当不同的介质之间有数据交互的时候,JAVA就使用流来实现。
数据源可以是文件,还可以是数据库,网络甚至是其他的程序

比如读取文件的数据到程序中,站在程序的角度来看,就叫做输入流
输入流: InputStream
输出流:OutputStream

3.字节流

InputStream字节输入流 
OutputStream字节输出流 
用于以字节的形式读取和写入数据

  • ASCII码

所有的数据存放在计算机中都是以数字的形式存放的。 所以字母就需要转换为数字才能够存放。
比如A就对应的数字65,a对应的数字97. 不同的字母和符号对应不同的数字,就是一张码表。
ASCII是这样的一种码表。 只包含简单的英文字母,符号,数字等等。 不包含中文,德文,俄语等复杂的。

  • 以字节流的形式读取文件内容

InputStream是字节输入流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileInputStream 是InputStream子类,以FileInputStream 为例进行文件读取

  • 以字节流的形式向文件写入数据

OutputStream是字节输出流,同时也是抽象类,只提供方法声明,不提供方法的具体实现。
FileOutputStream 是OutputStream子类,以FileOutputStream 为例向文件写出数据

注: 如果文件d:/lol2.txt不存在,写出操作会自动创建该文件。 
但是如果是文件 d:/xyz/lol2.txt,而目录xyz又不存在,会抛出异常

4.关闭流的方式

所有的流,无论是输入流还是输出流,使用完毕之后,都应该关闭。 如果不关闭,会产生对资源占用的浪费。 当量比较大的时候,会影响到业务的正常开展。

  • 在try中关闭

在try的作用域里关闭文件输入流,在前面的示例中都是使用这种方式,这样做有一个弊端;
如果文件不存在,或者读取的时候出现问题而抛出异常,那么就不会执行这一行关闭流的代码,存在巨大的资源占用隐患。 不推荐使用

  • 在finally中关闭

这是标准的关闭流的方式
1. 首先把流的引用声明在try的外面,如果声明在try里面,其作用域无法抵达finally.
2. 在finally关闭之前,要先判断该引用是否为空
3. 关闭的时候,需要再一次进行try catch处理

这是标准的严谨的关闭流的方式,但是看上去很繁琐,所以写不重要的或者测试代码的时候,都会采用上面的有隐患try的方式

  • 使用try()的方式

把流定义在try()里,try,catch或者finally结束的时候,会自动关闭
这种编写代码的方式叫做 try-with-resources, 这是从JDK7开始支持的技术

所有的流,都实现了一个接口叫做 AutoCloseable,任何类实现了这个接口,都可以在try()中进行实例化。 并且在try, catch, finally结束的时候自动关闭,回收相关资源。

5.字符流

Reader字符输入流 
Writer字符输出流 
专门用于字符的形式读取和写入数据

  • 使用字符流读取文件    

FileReader 是Reader子类,以FileReader 为例进行文件读取

  • 使用字符流把字符串写入到文件    

FileWriter 是Writer的子类,以FileWriter 为例把字符串写入到文件

6.编码/中文问题

  • 编码概念

计算机存放数据只能存放数字,所有的字符都会被转换为不同的数字。
就像一个棋盘一样,不同的字,处于不同的位置,而不同的位置,有不同的数字编号。
有的棋盘很小,只能放数字和英文
有的大一点,还能放中文
有的“足够”大,能够放下世界人民所使用的所有文字和符号

如图所示,英文字符 A 能够放在所有的棋盘里,而且位置都差不多
中文字符, 中文字符  能够放在后两种棋盘里,并且位置不一样,而且在小的那个棋盘里,就放不下中文

  • 常见编码

经常接触的编码方式有如下几种:
ISO-8859-1    ASCII    数字和西欧字母
GBK    GB2312    BIG5    中文
UNICODE    (统一码,万国码)

其中
ISO-8859-1 包含 ASCII
GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。
UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中

  • UNICODE和UTF

如果完全按照UNICODE的方式来存储数据,就会有很大的浪费。
比如在ISO-8859-1中,字符对应的数字是0x61
而UNICODE中对应的数字是 0x00000061,倘若一篇文章大部分都是英文字母,那么按照UNICODE的方式进行数据保存就会消耗很多空间

在这种情况下,就出现了UNICODE的各种减肥子编码, 比如UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果

UTF-8,UTF-16和UTF-32 针对不同类型的数据有不同的减肥效果,一般说来UTF-8是比较常用的方式

  • Java采用的是Unicode

写在.java源代码中的汉字,在执行之后,都会变成JVM中的字符。
而这些中文字符采用的编码方式,都是使用UNICODE. "中"字对应的UNICODE是4E2D,所以在内存中,实际保存的数据就是十六进制的0x4E2D, 也就是十进制的20013。

  • 文件的编码方式-eclipse

eclipse的编码方式:右键任意文本文件,点击最下面的"property"
就可以看到Text file encoding
也有ISO-8859-1,GBK,UTF-8等等选项。
其他的US-ASCII,UTF-16,UTF-16BE,UTF-16LE不常用。

  • 用FileInputStream 字节流正确读取中文

为了能够正确的读取中文内容
1. 必须了解文本是以哪种编码方式保存字符的
2. 使用字节流读取了文本后,再使用对应的编码方式去识别这些数字,得到正确的字符
如本例,一个文件中的内容是字符,编码方式是GBK,那么读出来的数据一定是D6D0。
再使用GBK编码方式识别D6D0,就能正确的得到字符

注: 在GBK的棋盘上找到的中字后,JVM会自动找到中在UNICODE这个棋盘上对应的数字,并且以UNICODE上的数字保存在内存中。

  • 用FileReader 字符流正确读取中文

FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了
而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK
FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:

new InputStreamReader(new FileInputStream(f),Charset.forName("UTF-8"));

在本例中,用记事本另存为UTF-8格式,然后用UTF-8就能识别对应的中文了。


解释: 为什么中字前面有一个?
如果是使用记事本另存为UTF-8的格式,那么在第一个字节有一个标示符,叫做BOM用来标志这个文件是用UTF-8来编码的。

7.缓存流

  • 概念

以介质是硬盘为例,字节流和字符流的弊端: 在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。

为了解决以上弊端,采用缓存流。 缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。

就好比吃饭,不用缓存就是每吃一口都到锅里去铲。用缓存就是先把饭盛到碗里,碗里的吃完了,再到锅里去铲

缓存流在写入数据的时候,会先把数据写入到缓存区,直到缓存区达到一定的量,才把这些数据,一起写入到硬盘中去。按照这种操作模式,就不会像字节流,字符流那样每写一个字节都访问硬盘,从而减少了IO操作

  • 使用缓存流读取数据

缓存字符输入流 BufferedReader 可以一次读取一行数据

  • 使用缓存流写出数据

PrintWriter 缓存字符输出流, 可以一次写出一行数据

  • flush

有的时候,需要立即把数据写入到硬盘,而不是等缓存满了才写出去。 这时候就需要用到flush

8.数据流

DataInputStream 数据输入流 
DataOutputStream 数据输出流

  • 直接进行字符串的读写

使用数据流的 writeUTF() 和 readUTF() 可以进行数据的格式化顺序读写
如本例,通过DataOutputStream 向文件  顺序写出 布尔值,整数和字符串。 然后再通过DataInputStream 顺序读入这些数据。

注: 要用DataInputStream 读取一个文件,这个文件必须是由DataOutputStream 写出的,否则会出现EOFException,因为DataOutputStream 在写出的时候会做一些特殊标记,只有DataInputStream 才能成功的读取。

9.对象流

对象流指的是可以直接把一个对象以流的形式传输给其他的介质,比如硬盘 
一个对象以流的形式进行传输,叫做序列化。 该对象所对应的类,必须是实现Serializable接口

  • 序列化一个对象

创建一个Hero对象,设置其名称为garen。 
把该对象序列化到一个文件garen.lol。
然后再通过序列化把该文件转换为一个Hero对象
注:把一个对象序列化有一个前提是:这个对象的类,必须实现了Serializable接口

10.System.in

System.out 是常用的在控制台输出数据的 
System.in 可以从控制台输入数据

  • System.in

  • Scanner读取整数和字符串

使用System.in.read虽然可以读取数据,但是很不方便
使用Scanner就可以逐行读取了

11.流关系图

Java常用知识点汇总(中级:异常处理,输入输出流)相关推荐

  1. Java常用知识点汇总(基础:数组,类与对象,接口与继承)

    目录 数组 1.引用 2.增强型for循环 3.复制数组 arraycopy() 4.针对数组的工具类 Arrays 5.选择法排序 6.冒泡排序 7.练习-二维数组中的查找(剑指offer) 类与对 ...

  2. Java常用英语汇总

    英语不好照样可以搞定Java编程-Java常用英语汇总 尚硅谷2016-11-11 14:48 题目:Java常用英语汇总(更新升级版) abstract (关键字) 抽象['.bstr.kt] ac ...

  3. JAVA常用单词汇总

    Java 常用英语汇总 abstract (关键字) access 抽象 ['.bstr.kt] vt.访问,存取 ['.kses]'(n.入口,使用权) n.算法 ['.lg.riem] algor ...

  4. list python 访问 键值对_基础|Python常用知识点汇总(中)

    字符串字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串.1.创建字符串 str1 = 'Hello World!' str2 = "Hello W ...

  5. Java常用命令汇总(笔记)

    Java常用命令汇总 文章目录 Java常用命令汇总 1.javac 将文件编译成.class文件 2.java 执行 .class文件,若类中没有main函数,则不能执行. 3.jar 主要用于打包 ...

  6. Java常见知识点汇总

    Java常见知识点汇总 基础概念与常识 1.Java 语言有哪些特点? 2.JVM vs JDK vs JRE 3.什么是字节码?采用字节码的好处是什么? 4.为什么不全部使用 AOT 呢? 5.为什 ...

  7. java基础知识大全,java 基础知识点汇总

    java 基础知识点汇总 问题一:我声明了什么! String s = "Hello world!"; 许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个Strin ...

  8. JAVA中级二 输入输出流,常见文件操作

    文章目录 输入输出流,常见文件操作 01 文件对象 1.1 创建一个文件对象 1.2 文件的常用方法1 1.3 文件的常用方法2 1.4 练习 02 什么是流 2.1 流的理解 2.2 文件输入流 2 ...

  9. 1.6 Java字节流的使用:字节输入/输出流、文件输入/输出流、字节数组输入/输出流

    InputStream 是 Java 所有字节输入流类的父类, OutputStream 是 Java 所有字节输出流类的父类, 它们都是一个抽象类,因此继承它们的子类要重新定义父类中的抽象方法. 下 ...

最新文章

  1. openresty 前端开发序
  2. 62 Celery远程调用
  3. java基础包的基本信息_JAVA 基础 之 基本数据类型、引用类型和包...
  4. 如何在 ASP.Net Core 使用 分布式缓存
  5. 使用Spring MVC进行资源版本控制
  6. poi为什么所有celltype都是string_不是所有向日葵都向阳,你知道为什么吗
  7. 帮助中心 开源_如何不获得开源帮助
  8. java ee 第二周作业 web应用后台运行过程
  9. Arduino IDE和ArduBlock 的下载安装
  10. Maven - 安装 配置
  11. 【图像压缩】基于matlab GUI DCT图像无损压缩【含Matlab源码 726期】
  12. 家里的无线网最近总是网速不稳定,一阵一阵的卡,是怎么回事?
  13. 关于扫码点餐多人实时共享订单的思考
  14. 新代系统9服务器警报,新代系统数控铣加工中心。新代系统龙门加工中心故障与报警...
  15. PS实战操作之蒙版、路径
  16. 【小玩意】锟斤拷语加密器
  17. 如何调教ChatGpt 让它听话
  18. i.MX6ULL终结者电容触摸实验程序设计
  19. RDLC报表 报表数据(参数栏)不显示怎么办?
  20. iOS 苹果开发者账号--个人账号、公司账号、企业账号的区别

热门文章

  1. linux安全狗配置apache参数,Linux服务器安全狗Apache版本安装步骤
  2. 出国程序---去体检打印成绩单
  3. 打印耗材,原配的才是真正贴心的
  4. 常用IDE/编辑器 格式化代码快捷键
  5. GoodNotes5下载之使用教程
  6. DS1302异常 秒数超过60 走时过快问题
  7. win8 Oracle 12c安装
  8. 天津搜索引擎营销SEM(二)
  9. 使用.net 操作 微信公众平台 —— 第三方登录
  10. 如何把数字证书导入到Windows根证书存储区