一、异常的概述和继承体系
异常的概念:异常:就是程序出现了不正常的情况。
指的就是程序所发生的错误( 语法错误不是异常 )
例如:ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
常见的异常有:
IndexOutOfBoundsException 、NullPointerException、StringIndexOutOfBoundsException
异常的体系的介绍:
Throwable 类是 Java 语言中所有错误或异常的超类。
Error 是 Throwable 的子类, 用于指示合理的应用程序不应该试图捕获的严重问题。
也就是说针对程序发生了Error的情况,Java程序本身是无能为力的,比如说:硬件层面的问题,内存不足等。
所以,针对Error的问题我们不处理。
Exception 类及其子类是 Throwable的一种形式, 它指出了合理的应用程序想要捕获的条件 。
也就是说针对程序发生了Exception的情况,是我们需要处理的问题。
Exception的分类:
运行期的异常(RunTimeException):在编译期是不处理的,在程序运行时候出现了问题,需要我们回来修改代码。
编译期的异常(非RunTimeException):在编译期就必须处理,否则程序不能通过编译,就更不能正常的执行了。
理解: 未雨绸缪异常, 在编译的过程中, 程序检测到这段代码可能会出现怎样的问题, 例如FileNotFoundException
这时候就必须对异常进行预处理.
二、JVM针对异常的默认处理方式
异常有哪几种处理方式?异常分类两种处理方式:
A. 问题很小, 自己能处理
try..catch
B. 问题很大, 自己处理不了 -> 找上级领导帮忙处理.
throw throws抛出异常.
jvm默认是如何处理异常的?
问题抛给main方法, 主方法的调用者是jvm, jvm接收到异常之后, 就将异常信息输出在了控制台.
三、异常处理方案try…catch
什么情况下使用try..catch处理异常的方式发现问题是可以自己解决的.
格式:
try{
可能会出现异常的代码,检测异常
}catch( 将要捕获的异常){
异常的处理方式
}
try {
int[] arr = {11, 22, 33, 44};
System.out.println(arr[5]); // new ArrayIndexOutOfBoundsException();
} catch (NullPointerException e){
System.out.println("空指针异常");
} catch (ArrayIndexOutOfBoundsException e){
System.out.println("索引越界了, 回去好好看看代码");
}
System.out.println("...............");
toString():
简短描述
getMessage(): 返回错误信息
printStackTrace() : 返回错误的完整信息(错误的行数, 错误的异常, 错误的原因)
练习:
需求: 编写一段代码, 要求代码中会产生索引越界异常
并使用try...catch进行处理
分析:
第一步:定义数组
第二步:在打印语句中访问不存在的索引
第三步:将可能发生问题的代码用try包裹
第四步:catch中捕获IndexOutOfBoundsException
第五步:对异常进行处理,并用printStackTrace打印出异常信息
public class Demo02_Exception {
public static void main(String[] args) {
try {
int[] iArr = {11,22,33,44,55};
System.out.println(iArr[10]);
} catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
try...catch
的执行顺序:
首先会执行try语句中的代码, 看被try包裹的代码是否产生异常
是 : 异常被catch进行捕获, 然后走catch语句中的代码
不是 :程序继续向下执行
好处: 使用try..catch语句自己将问题处理掉之后, 不会影响到后续代码的执行
注意: 如果try语句中的代码没有发生异常, 那么catch语句将不会执行.
catch 中只能捕获()中声明的异常, 如果想要捕获所有的异常, 可以写成父类 Exception
alt+ shift + z --> try..catch
如果catch捕获的是多个异常, 那么大的异常需要放在最下面!!!
四、编译时异常和运行时异常的区别
1. 编译时异常指的就是, 在编译的过程中, 程序检测到某段代码可能会发送怎样的问题, 这时候就必须对代码进行异常处理.否则编译失败
FileInputStreamfis = new FileInputStream("D:\\info.txt");
2. 运行时异常指的是编译通过了, 语法也通过了, 但是运行的时候出现的错误.
运行时异常往往都是我们程序员自身所发生的错误,是需要回头去修改源代码的.
五、异常处理方案throws
什么情况下需要将异常抛出?自己处理不了
案例演示: setAge赋值错误.
publicclass Person {
privateint age;
publicint getAge() {
returnage;
}
publicvoid setAge(int age) throws Exception{
if(age>= 0 && age <= 200){
this.age= age;
}else{
//当使用throw抛出异常的时候, 方法上必须使用throws声明抛出的异常类型
thrownew Exception("年龄非法");
}
}
@Override
publicString toString() {
return"Person [age=" + age + "]";
}
}
思路:
1. 如何抛出异常?
throw new 异常对象();
2. 抛出异常对象之后呢?
需要在方法的声明上,告知调用者, 该方法抛出的是哪一个异常
throws 异常类名
3. 调用者需要注意什么?
如果调用的方法是带有异常的,那么就必须进行处理
结论: throw throws的区别是什么?
throw 是真正抛出异常的,而throws仅仅是对方法的一个声明, 告知调用者, 此方法存在异常, 使用的时候需要进行异常处理
注意:
如果抛出的异常是RuntimeException的话, 那么就不需要throws的声明.
六、File类的概述和构造方法
A:File类的概述和作用a: File的概念
File 类是文件和目录路径名的抽象表示形式
Java 中把文件或者目录(文件夹)都封装成File对象
我们要去操作硬盘上的文件,或者文件夹只要找到File这个类即可
总结:
在java当中, 使用file类来表示(文件路径)或者是(文件夹路径)
思路: 如果今后要操作硬盘中的某一个文件或者是文件夹的话, 那么首先要考虑将要操作数据的路径封装成file对象.
B: File类的常用构造方法:
File(String pathname) :将一个字符串路径封装成File对象
File(String parent,String child):传入一个父级路径和子级路径
File(File parent,Stringchild):传入一个File类型的父级路径和子级路径
七、File类的创建功能
boolean createNewFile():指定路径不存在该文件时时创建文件,返回true,否则返回falseboolean mkdir():当指定的单级文件夹不存在时创建文件夹并返回true,否则返回false
boolean mkdirs():当指定的多级文件夹某一级文件夹不存在时,创建多级文件夹并返回true,否则返回false
八、File类的删除功能
boolean delete():删除文件或者删除单级文件夹注意: delete方法只能删除的是单个文件, 或者是删除单级文件夹, 单级文件夹只能是空文件夹
总结:
相对路径: 相对于当前项目下的xxx文件, 也可以是文件夹 -->new File("abc.txt");
绝对路径: 从盘符的根目录下开始, 明确到指向哪一个文件 -->D:\\aaa.txt
九、File类的判断和获取功能
判断功能boolean exists():判断指定路径的文件或文件夹是否存在
boolean isDirectory():判断当前的目录是否存在
boolean isFile():判断当前路径是否是一个文件
获取功能
String getAbsolutePath():获取文件的绝对路径,返回路径的字符串
String getPath():获取File对象中封装的路径
String getName():获取文件或文件夹的名称
案例演示
需求: 键盘录入一个文件夹路径
如果录入的文件不存在给出提示
如果录入的是一个文件,给出提示
直到录入了正确的文件夹路径为止,程序终止
import java.io.File;
import java.util.Scanner;
public class Demo2_File {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请输入一个文件夹路径:");
String path = sc.nextLine();
File f = new File(path);
if(!f.exists()){
System.out.println("你录入的文件夹路径不存在,请重新输入!");
} else if(f.isFile()){
System.out.println("您录入的是文件,请重新输入:");
} else{
System.out.println("您录入的文件夹路径是:" + f.getAbsolutePath());
break;
}
}
sc.close();
}
}
十、IO流的概述和分类
什么是IO流?I(input)O(output)流代表的是输入流和输出流, 一般用于数据传输, 经常体现在文件的上传和下载
IO流的分类有哪些?
按照流向分:输入流 -> 用来读取某个文件的
输出流 -> 用来将数据写出到某个文件
按照类型分:
字节流 ->所有的数据都以字节的形式进行传输
字符流 ->用来读写纯文本文件的.
注意: IO流的抽象父类有哪些?
字节流:
字节输入流: InputStream
字节输出流: OutputStream
小窍门 : 后缀以Stream为结尾的都是字节流
字符流:
字符输入流:
Reader
字符输出流:
Writer
小窍门 : 后缀以Reader为结尾的都是字符输入流
后缀以Writer为结尾的都是字符输出流
十一、FileOutputStream写数据
构造方法FileOutputStream(Stringname) : 将要操作的数据目的的路径,传入构造方法中, 以字符串的形式
FileOutputStream(Filefile) : 将要操作的数据目的的路径,传入构造方法中, 以File对象的形式
写出数据使用的成员方法
write(intb)代码:
//IO流操作的基本步骤
// 1.创建字节输出流对象
// 输出流关联文件, 如果文件不存在, 则自动创建
FileOutputStreamfos = new FileOutputStream("a1.txt");
// 2.调用输出流对象的方法写出数据
Strings = "调用输出流对象的方法写出数据";
fos.write(s.getBytes());
// 3.关闭流释放资源!
fos.close();
十二、FileOutputStream写数据的三种方式
public void write(int b):一次写一个字节public void write(byte[] b):一次写一个字节数组
public void write(byte[] b,intoff,int len):一次写一个字节数组的一部分
十三、FileOutputStream如何实现换行和追加写数据
如何实现数据的换行写入?调用write方法写出"\r\n"即可
如何实现数据的尾部追加动作?
FileOutputStream(Stringname, boolean append)
在构造方法的参数中,传入true,开启尾部追加
十四、FileOutputStream写数据加入异常处理
FileOutputStreamfos = null;
try {
//FileOutputStream fos = new FileOutputStream("d.txt");
//fos = new FileOutputStream("z:\\d.txt");
fos= new FileOutputStream("d.txt");
fos.write("hello".getBytes());
}catch (IOException e) {
e.printStackTrace();
} finally{
if(fos != null) {
//释放资源
try{
fos.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}
十五、FileInputStream读数据方式1一次读取一个字节
构造方法: FileInputStream(String name)FileInputStream是通过哪个方法读取数据的? 文件的末尾结束标记为?
read();
-1
输入和输出的注意事项:
输出流操作文件, 如果文件不存在的话, 程序将会自动创建出一个
输入流读取文件, 如果文件不存在, 则会抛出FileNotFoundException
十六、FileInputStream读数据方式2一次读取一个字节数组.
单个字节读取效率如何?非常低, 可以使用容器的方式解决此问题
一次读取一个字节数组的注意问题:
如何解决?
//1. 创建输入流对象关联数据源
FileInputStreamfis = new FileInputStream("aaa\\aaa.txt");
//2. 定义字节数组容器, 为了提高读取的效率
byte[]bys = new byte[2];
//3. 定义临时变量, 用于不断的记录read方法返回的有效字节个数
intlen = 0;
//4. 使用while循环不断的读取, 将read方法的返回值赋值给len
while((len= fis.read(bys)) != -1){
System.out.print(newString(bys, 0, len));
}
fis.close();
依赖的方法:
String(byte[]bytes, int offset, int length) -> 构造方法
将传入的字节数组的一部分,转换成字符串
bytes: 数据源
offset: 起始的索引位置
length: 转换的个数
十七、字节流练习之复制文本文件
需求拷贝文本文件
分析:
第一步: 创建输入输出流对象关联数据源和数据目的
第二步: 定义字节数组,为了提高效率
第三步: 将数据通过while循环不断读取到字节数组中
第四步: 将数据从字节数组中取出并写出
第五步: 释放资源
// 1.创建输入流对象关联数据源
FileInputStreamfis = new FileInputStream("窗里窗外.txt");
// 2.创建输出流对象关联数据目的
FileOutputStreamfos = new FileOutputStream("copyText.txt");
// 3.使用java程序读取数据源中的数据, 将读取到的数据写出到目标文件中
byte[]bys = new byte[2048];
intlen = 0;
while((len= fis.read(bys)) != -1){
fos.write(bys,0, len);
}
// 4.关闭流释放资源
fis.close();
fos.close();
十八、字节流练习之复制图片
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Demo4_Stream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("aaa.jpg");
FileOutputStream fos = new FileOutputStream("bbb.jpg");
byte[] bytes = new byte[2048];
int len = 0;
while((len = fis.read(bytes))!=-1){
fos.write(bytes, 0, len);
}
fis.close();
fos.close();
}
}