1、异常机制(重点)
1.1、基本概念
- 异常就是"不正常"的含义,在Java语言中主要指程序执行中发生的不正常情况。
- java.lang.Throwable类是Java语言中错误(Error)和异常(Exception)的超类。
- 其中Error类主要用于描述Java虚拟机无法解决的严重错误,通常无法编码解决,如:JVM挂掉了等。
- 其中Exception类主要用于描述因编程错误或偶然外在因素导致的轻微错误,通常可以编码解决,如:0作为除数等。
1.2、异常的分类
- java.lang.Exception类是所有异常的超类,主要分为以下两种:
- RuntimeException - 运行时异常,也叫作非检测性异常
- IOException和其它异常 - 其它异常,也叫作检测性异常,所谓检测性异常就是指在编译阶段都能被编译器检测出来的异常。
- 其中RuntimeException类的主要子类:
算术异常
ArithmeticException
数组下标越界异常
ArrayIndexOutOfBoundsException
空指针异常
NullPointException
类型转换异常
ClassCastException
数字格式异常
NumberFormatException
注意:
当程序执行过程中发生异常但又没有手动处理时,则由JAVA虚拟机采用默认方式处理异常,而默认处理方式就是:打印异常得名称,异常发生得原因,异常发发生得位置以及终止程序。
1.3、异常的避免
- 在以后的开发中尽量使用if条件判断来避免异常的发生。
- 但是过多的if条件判断会导致程序的代码加长、臃肿,可读性差。
//会发生算术异常 ArithmeticException
int a=10;
int b=0;
if(0 != b)
{
System.out.println(a/b);
}
//会发生数组下标异常 ArrayIndexOutOfBoundsException
int[] arr=new int[5];
int pos=5;
if(pos >= 0 && pos < arr.length) {
System.out.println(arr[pos]);
}
//会发生空指针异常 NullPointerException
String str=null;
if(null != str){
System.out.println(str.length());
}
//会发生类型转换异常 ClassCastException
Exception ex=new Exception();
if(ex instanceof IOException){
IOException io=(IOException)ex;
}
//会发生数字格式异常 NumberFormatException
String str2="123a";
if(str2.matches("\\d+"))
{
System.out.println(Integer.parseInt(str2));
}
1.4、异常的捕获
- 语法格式
try {
编写可能发生异常的代码;
}
catch(异常类型 引用变量名) {
编写针对该类异常的处理代码;
}
...
finally {
编写无论是否发生异常都要执行的代码;
}
public class ExceptionCatchTest {
public static void main(String[] args) {
// 创建一个FileInputStream类型的对象与d:/a.txt文件关联,打开文件
FileInputStream fis = null;
try {
System.out.println("1");
// 当程序执行过程中发生了异常后直奔catch分支进行处理
fis = new FileInputStream("d:/a.txt");
System.out.println("2");
} catch (FileNotFoundException e) {
System.out.println("3");
e.printStackTrace();
System.out.println("4");
}
// 关闭文件
try {
System.out.println("5");
fis.close();
System.out.println("6");
} /*catch (Exception e) {
e.printStackTrace();
}*/ catch (IOException e) {
System.out.println("7");
e.printStackTrace();
System.out.println("8");
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("世界上最真情的相依就是你在try我在catch,无论你发神马脾气我都默默承受并静静的处理,到那时再来期待我们的finally!");
// 当程序执行过程中没有发生异常时的执行流程:1 2 5 6 世界上...
// 当程序执行过程中发生异常又没有手动处理空指针异常时的执行流程:1 3 4 5 空指针异常导致程序终止
// 当程序执行过程中发生异常并且手动处理空指针异常时的执行流程: 1 3 4 5 世界上...
// 手动处理异常和没有处理的区别:代码是否可以继续向下执行
}
}
- 注意事项
a.当需要编写多个catch分支时,切记小类型应该放在大类型的前面;
b.懒人的写法: catch(Exception e) {}
c.finally通常用于进行善后处理,如:关闭已经打开的文件等。
- 执行流程
try {
a;
b; - 可能发生异常的语句
c;
}catch(Exception ex) {
d;
}finally {
e;
}
当没有发生异常时的执行流程:a b c e;
当发生异常时的执行流程:a b d e;
public class ExceptionFinallyTest {
// 笔试考点
public static int test() {
try {
int[] arr = new int[5];
System.out.println(arr[5]);
return 0;
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
return 1;
} finally {
return 2; // 提交结束方法并返回数据
}
}
public static void main(String[] args) {
try {
int ia = 10;
int ib = 0;
System.out.println(ia / ib);
} catch (ArithmeticException e) {
e.printStackTrace();
String str1 = null;
//str1.length(); // 会发生空指针异常
} finally {
System.out.println("无论是否发生异常都记得来执行我哦!"); // 依然是执行
}
System.out.println("Over!"); // 不执行了
System.out.println("----------------------------------------");
int test = test();
System.out.println("test = " + test); // 2
}
}
1.5、异常的抛出
- 基本概念
在某些特殊情况下有些异常不能处理或者不便于处理时,就可以将该异常转移给该方法的调用者,这种方法就叫异常的抛出。当方法执行时出现异常,则底层生成一个异常类对象抛出,此时异常代码后续的代码就不再执行。
- 语法格式
访问权限 返回值类型 方法名称(形参列表) throws 异常类型1,异常类型2,...{ 方法体; }
如:public void show() throws IOException{}
- 方法重写的原则
a.要求方法名相同、参数列表相同以及返回值类型相同,从jdk1.5开始支持返回子类类型;
b.要求方法的访问权限不能变小,可以相同或者变大;
c.要求方法不能抛出更大的异常;
- 注意:
子类重写的方法不能抛出更大的异常、不能抛出平级不一样的异常,但可以抛出一样的异常、更小的异常以及不抛出异常。
- 经验分享
若父类中被重写的方法没有抛出异常时,则子类中重写的方法只能进行异常的捕获处理。
若一个方法内部又以递进方式分别调用了好几个其它方法,则建议这些方法内可以使用抛出的方法处理到最后一层进行捕获方式处理。
//main方法不建议抛出异常,JVM负担很重
try {
show();
} catch (IOException e) {
e.printStackTrace();
}
public static void show() throws IOException {
FileInputStream fis=new FileInputStream("d:/a.txt");
fis.close();
}
import java.io.IOException;
public class ExceptionMethod {
public void show() throws IOException {}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionThrowsTest {
public static void show() throws IOException {
FileInputStream fis = new FileInputStream("d:/a.txt");
System.out.println("我想看看你抛出异常后是否继续向下执行???");
fis.close();
}
public static void test1() throws IOException {
show();
}
public static void test2() throws IOException {
test1();
}
public static void test3() throws IOException {
test2();
}
// 不建议在main方法中抛出异常 JVM负担很重
public static void main(String[] args) /*throws IOException*/ {
try {
show();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("------------------------------------");
try {
test3();
} catch (IOException e) {
e.printStackTrace();
}
}
}
1.6、自定义异常
- 基本概念
当需要在程序中表达年龄不合理的情况时,而Java官方又没有提供这种针对性的异常,此时就需要程序员自定义异常加以描述。
-
实现流程
a.自定义xxxException异常类继承Exception类或者其子类。
b.提供两个版本的构造方法,一个是无参构造方法,另外一个是字符串作为参数的构造方法。异常的产生throw new 异常类型(实参);
如:
- throw new AgeException("年龄不合理!!!");
- Java采用的异常处理机制是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护。
2、File类(重点)
2.1、基本概念
- java.io.File类主要用于描述文件或目录路径的抽象表示信息,可以获取文件或目录的特征信息, 如:大小等。
2.2、常用的方法
/**
* @author XiceSberg
* @date 2020/8/24 22:50
* @description
*/
public class FileTest {
public static void main(String[] args) {
// 1.构造File类型的对象与d:/a.txt文件关联
File file=new File("d:/a.text");
// 2.若文件存在则获取文件的相关特征信息并打印后删除文件
if(file.exists())
{
System.out.println("文件的名称是:" +file.getName());
System.out.println("文件的大小是:"+file.length());
Date date=new Date(file.lastModified());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("文件的最后一次修改时间:" +sdf.format(date));
// 绝对路径: 主要指以根目录开始的路径信息,如:c:/ d:/ /..
// 相对路径: 主要指以当前目录所在位置开始的路径信息,如:./ ../ 相对路径
System.out.println("文件的绝对路径信息是:" +file.getAbsolutePath());
System.out.println(file.delete() ? "删除成功" : "删除失败");
}else
{
// 3.若文件不存在则创建新的空文件
try {
System.out.println(file.createNewFile() ? "文件创建成功": "文件创建失败!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}