欢迎关注我的公众号【软件大爆炸】
Java学习中的碎碎念
Java中易忽略的基础知识
Java面向对象基础
Java中的核心类
Java抽象类和接口
Java中的异常
Java中的泛型与集合
Java中的错误分三类:
Java异常类之间的严格继承关系
Java中的异常类主要分为两类:
Throwable
是所有异常类的父类, Error
和 Exception
都继承此类。当程序产生Error
时,因系统无法捕获Error
并处理,程序员将无能为力,程序只能中断;而当发生 Exception
时,系统可以捕获并做出处理。
Exception异常从编程角度又可以分为以下两种类型:
非检查型异常 | 类名 | 说明 |
---|---|---|
ArrayIndexOutOfBoundsException | 数组下标越界异常 | |
NullPointerExpection | 空指针访问异常 | |
NumberFormatException | 数字格式化异常 | |
ArithmeticException | 算术异常,比如除以零溢出 | |
ClassCastException | 类型转化不匹配异常 |
检查型异常 | 类名 | 说明 |
---|---|---|
SQLException | 数据库访问异常 | |
IOException | 文件操作异常 | |
FileNotFoundException | 文件不存在异常 | |
ClassNotFoundException | 类没有找到异常 |
程序员必须对检查型的异常进行处理,否则程序编译不通过,无法运行。
异常处理:为了使程序出现异常时也能正常运行下去,需要对异常进行相关的处理操作。
Java提供的异常处理机制有两种:
try...catch
捕获异常。将可能产生异常的代码放在try语句中进行隔离,如果遇到异常,程序会停止执行try
块的代码,跳到 catch
块中进行处理throws
声明抛出异常。当前方法不知道如何处理所出现的异常,该异常应由上一级调用者进行处理,可在定义该方法时使用 throws
声明抛出异常。关于try...catch
代码举例:
public class ExceptionDemo1 {
public static void main(String[] args) {
try {
int i = 1/0;
System.out.println("i的值是"+i);
}catch (Exception e){
e.printStackTrace();
}
System.out.println("代码结束!");
}
}
java.lang.ArithmeticException: / by zero
at club.BOOKJava8.ExceptionDemo1.main(ExceptionDemo1.java:6)
代码结束!
Process finished with exit code 0
名称 | 说明 |
---|---|
getMessage() | 返回该异常的详细描述字符串 |
printStackTrace() | 将该异常的跟踪栈信息输出到标准错误输出 |
printStackTrace(PrintStream s) | 将该异常的跟踪栈信息输出到指定输出流 |
getStactTrace() | 方法返回该异常的跟踪栈信息 |
import java.util.Scanner;
public class ExceptionDemo1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] array = new int[3];
try {
System.out.println("请输入第一个数");
String str = scanner.next();
int n1 = Integer.parseInt(str);
System.out.println("请输入第二个数");
int n2 = scanner.nextInt();
array[1] = n1/n2;
array[3] = n1 * n2;
System.out.println("两个数字之和是:"+(n1+n2));
}catch (NumberFormatException ex){
System.out.println("数字格式化异常");
}catch (ArithmeticException ex){
System.out.println("算数异常");
}catch (ArrayIndexOutOfBoundsException ex){
System.out.println("下标越界异常");
}catch (Exception ex){
System.out.println("其他未知异常");
}
System.out.println("程序到此结束");
}
}
第一组结果:
请输入第一个数
8
请输入第二个数
0
算数异常
程序到此结束
第二组结果:
请输入第一个数
8
请输入第二个数
6
下标越界异常
程序到此结束
捕获异常的顺序和 catch语句的顺序有关,因此安排 catch语句的顺序时,首先应该捕获一些子类异常,然后再捕获父类异常。
关于try...catch...finally
在某些时候,程序在try
块中打开了一些物理资源,例如:数据库连接、网络连接以及磁盘文件读写等,针对这些物理资源,不管是否有异常发生,都必须显式回收;而在try
块中旦发生异常,可能会跳过显示回收代码直接进入 catch块,导致没有正常回收资源。这种情况下就要求某些特定的代码必须被执行。在Java异常处理机制中,提供了 finally
块,可以将回收代码放入此块中,不管try
块中的代码是否出现异常,也不管哪一个 catch
块被执行,甚至在try
块或 catch
块中执行了 return
语句, finally
块总会被执行。
注意:
Java垃圾回收机制不会回收任何物理资源,垃圾回收机制只能回收堆内存中对象所占用的内存。在Java程序中,通常使用 finally
回收物理资源。
代码示例:
import java.io.FileInputStream;
import java.io.IOException;
public class Exception2 {
public static void main(String[] args) {
FileInputStream fis = null;
try{
fis = new FileInputStream("公众号软件大爆炸.txt");
}catch (IOException ioe){
System.out.println(ioe.getMessage());
return ;
}finally {
if (fis != null){
try{
fis.close();
}catch (IOException ioe){
ioe.printStackTrace();
}
}
System.out.println("执行finally块里的资源回收!");
}
}
}
公众号软件大爆炸.txt (系统找不到指定的文件。)
执行finally块里的资源回收!
从Java7开始,增强了try语句的功能,允许在try关键字后紧跟一对小括号,在小括号中可以声明、初始化一个或多个资源,当try语句执行结束时会自动关闭这些资源.
import java.io.FileInputStream;
import java.io.IOException;
public class AutoCloseDemo {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("软件大爆炸.txt")) {
//do something to file
}catch (IOException ioe){
System.out.println(ioe.getMessage());
}
}
}
软件大爆炸.txt (系统找不到指定的文件。)
Process finished with exit code 0
抛出异常可以使用 throw
或 throws
关键字
throw代码示例
import java.util.Scanner;
public class ThrowDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("请输入年龄:");
int age = scanner.nextInt();
if (age < 0 || age > 80){
throw new Exception("请输入一个合法的年龄,年龄必须在0-80之间");
}
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println("程序结束了!");
}
}
请输入年龄:
99
java.lang.Exception: 请输入一个合法的年龄,年龄必须在0-80之间
at club.BOOKJava8.ThrowDemo.main(ThrowDemo.java:12)
程序结束了!
throws代码示例
import java.util.Scanner;
public class ThrowsDemo {
public static void main(String[] args) {
try {
myThrowsFunction();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (ArithmeticException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void myThrowsFunction() throws NumberFormatException, ArithmeticException, Exception{
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = scanner.next();
int n1 = Integer.parseInt(str);
System.out.println("请输入第二个数");
int n2 = scanner.nextInt();
System.out.println("您输入的两个数字相除为:" + (n1 / n2));
}
}
请输入一个字符串
8
请输入第二个数
0
java.lang.ArithmeticException: / by zero
at club.BOOKJava8.ThrowsDemo.myThrowsFunction(ThrowsDemo.java:25)
at club.BOOKJava8.ThrowsDemo.main(ThrowsDemo.java:8)
Process finished with exit code 0
也可以使用自定义异常:
自定义异常类都继承 Exception
或 RuntimeException
类
import java.util.Scanner;
public class MyExceptionDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try{
System.out.println("请输入年龄:");
int age = scanner.nextInt();
if (age < 0 || age > 80){
throw new AgeException("年龄不合法,必须在0-80之间");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
class AgeException extends Exception{
public AgeException(){
}
public AgeException(String msg){
super(msg);
}
}
请输入年龄:
88
club.BOOKJava8.AgeException: 年龄不合法,必须在0-80之间
at club.BOOKJava8.MyExceptionDemo.main(MyExceptionDemo.java:12)
Process finished with exit code 0