文章目录
代码入门
package 异常;
public class Exception01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int num1 = 10;
int num2 = 0;
//1. 因为num2为0,则程序抛出异常 ArithmeticException
//2. 当抛出异常后,下面的代码不再执行
// int res = num1 / num2;
//3.如果程序员认为一段代码可能出现异常,可以使用try catch的异常处理机制
//4.从而保证程序的健壮性
//5.如果执行异常处理,那么即使出现了异常,程序可以继续执行
try {
int res = num1 / num2;
} catch(Exception e) {
//e.printStackTrace();
System.out.println("出现异常的原因是:" + e.getMessage()); //输出异常信息
}
System.out.println("程序继续运行……");
}
}
异常的概念
- java语言中,将程序执行中发生的不正常情况称为"异常"。【开发过程中的语法错误和逻辑错误不是异常】。
- 执行过程中所发生的异常事件分为两类:
ERROR
:java虚拟机无法解决的严重问题,如:JVM
系统内部错误、资源耗尽等严重情况。比如:StackOverflowError
【栈溢出】和OOM
【out of memory
】,error
是严重错误,程序会崩溃。Exception
:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:空指针访问,试图读取不存在的文件,网络连接中断等,exception
分为两大类:运行时异常和编译时异常。
异常体系图
类图中虚线是实现接口,实现是继承
- 运行时异常,编译器不要求强制处置的异常,一般是指编程时的逻辑错误,是程序员应该避免出现的异常。
java.lang.RuntimeException
类以及它的子类都是运行时异常。 - 对于运行时异常,可以不作处理,因为这类异常很普遍,有默认处理机制,若全处理可能会对程序的可读性和运行效率产生影响。
- 编译时异常,是编译器要求必须处置的异常。
五大常见的运行时异常
NullPointException
空指针异常:当应用程序在需要对象的地方使用null时,抛出该异常。
public class NullPointException {
public static void main(String[] args) {
// TODO Auto-generated method stub
String name = null;
System.out.println(name.length());
}
}
ArithmeticExceptionpoint
数学运算异常:当出现异常的运算条件时,抛出此异常。例如:“一个整数除以零”时,抛出此类的一个实例。
public class Exception01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int num1 = 10;
int num2 = 0;
//1. 因为num2为0,则程序抛出异常 ArithmeticException
//2. 当抛出异常后,下面的代码不再执行
// int res = num1 / num2;
//3.如果程序员认为一段代码可能出现异常,可以使用try catch的异常处理机制
//4.从而保证程序的健壮性
//5.如果执行异常处理,那么即使出现了异常,程序可以继续执行
try {
int res = num1 / num2;
} catch(Exception e) {
//e.printStackTrace();
System.out.println("出现异常的原因是:" + e.getMessage()); //输出异常信息
}
System.out.println("程序继续运行……");
}
}
ArrayIndexOutBoundsException
越组下标越界异常:用非法索引访问数组时抛出的异常,如果索引为负或大于等于数组大小,则该索引为非法索引。ClassCastException
类型转换异常:当试图将对象强转为不是实例的子类时抛出该异常。
public class ClassCastException {
public static void main(String[] args) {
// TODO Auto-generated method stub
A b = new B(); //上转型,true
B b2 = (B)b; //下转型,true
C c = (C)b; //抛出ClassCastException异常
}
}
class A {}
class B extends A {}
class C extends A {}
NumberFormatException
数字格式不正确异常:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适应格式时,抛出该异常—>使用异常我们可以确保输入是满足条件数字。
public class NumberFormatException {
public static void main(String[] args) {
// TODO Auto-generated method stub
String name = "小明";
//将String转为int
int num = Integer.parseInt(name);
System.out.println(num);
}
}
编译异常
编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译。
常见的编译异常(网路、数据库、文件操作时常见)
SQLException
:操作数据库时,查询表可能发生异常。
IOException
:操作文件时,发生的异常。
FileNoFoundException
:当操作一个不存在的文件时,发生异常。
ClassNotFoundException
:记载类,而该类不存在时,发生异常。
EOFException
:操作文件,到文件末尾,发生异常。
IIIegalArguementException
:参数异常
异常处理详解
try-catch异常处理
try-catch-finally
:程序员在代码中捕获发生的异常,自行处理
try {
代码可能有异常;
} catch(Exception e) {
捕获到异常,对异常的处理;
1.当异常发生时
2.系统将异常封装成Exception对象e,传递给catch
3.得到异常对象后,程序员自己处理
4.注意:如果没有发生异常,catch代码块不执行
} finally { //可写可不写
1.不管try代码块是否有异常,始终要执行finally
2.所以,通常将释放资源的代码放在finally
}
- 如果异常发生了,则异常后面的代码不会执行,直接进入
catch
块中。 - 如果异常没有发生,则顺序执行
try
后面的代码块,不会进入到catch
。 - 如果希望不管是否发生异常,都执行某段代码(比如关闭连接、释放资源等),则使用
finally
。 try-catch-finally
中,先执行try
,在执行finally
,最后执行catch
。
public class Exception02 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String str = "小明";
int a = Integer.parseInt(str);
System.out.println("数字:" + a);
} catch (NumberFormatException e) {
System.out.println("异常信息=" + e.getMessage());
}
finally {
System.out.println("程序继续……");
}
}
}
- 可以有多个
catch
语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,比如(Exception
在后,NullPointException
在前),如果发生异常,只会匹配一个catch
。
public class Exception03 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Person person = new Person();
person = null; //空指针异常
System.out.println(person.getName());
int n1 = 10;
int n2 = 0;
int res = n1 / n2; //数字运算异常
} catch(NullPointerException e) {
System.out.println("空指针异常" + e.getMessage());
}
catch (ArithmeticException e) {
System.out.println("算数异常" +e.getMessage());
} catch(Exception e) { //父类异常必须要写在后面
System.out.println(e.getMessage());
} finally {
}
}
}
class Person {
private String name;
public String getName() {
return name;
}
}
- 可以使用
try-finally
组合,这种用法相当于没有捕获异常,因此程序会直接崩掉。应用场景:总是执行一段代码,不管是否发生异常,都必须执行。运行完finally
里面的语句后不管后面有没有语句,均不执行,并且程序崩掉。
throws异常处理
throws
:将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者是JVM
。
JVM
处理异常机制:输出异常信息,中断并退出程序。
public class Exception01 {
7
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
int num1 = 10;
int num2 = 0;
int res = num1 / num2; //没有try catch,则默认在主类throw抛出异常给JVM
}
}
- 如果一个方法中的语句执行时可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示的声明异常,表面该方法不对这些异常进行处理,而该方法的调用者负责处理。
- 在此方法中用
throws
语句可以声明抛出异常的列表,throws
后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。 - 对于编译异常,程序必须处理,比如
try-catch
或者throws
。 - 对于运行时异常,程序中如果没有处理,默认就是
throws
的方式处理。 - 子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型。
class Father {
public void method() throws RuntimeException {
}
}
class Son extends Father {
@Override
public void method() throws NullPointerException {
}
}
- 在
throws
过程中,如果有方法try-catch
,就相当于处理异常,就可以不必throws
。
自定义异常
当程序中那个出现了某些错误,但该错误信息并没有在
Throwsable
子类中描述处理,这个时候可以自己设计异常类,用于描述错误信息。
- 定义类:自定义异常类名(程序员自己写),继承
Exception
或者RuntimeException
。 - 如果继承
Exception
,属于编译异常。 - 如果继承
RuntimeException
,属于运行异常(一般来说,继承RuntimeException
)。 - 把自定义异常做成运行时异常,好处是即把自定义异常可以使用默认的处理机制
public class throws01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int age = 180;
if(!(age>=18 && age<=120)) {
throw new AgeException("年龄需要在18-120之间");
}
System.out.println("你的年龄范围正确");
}
}
//自定义异常
class AgeException extends RuntimeException {
public AgeException(String message) { //构造器
super(message);
}
}
throw和throws的对比
练习
public class throws02 {
public static void main(String [] args) {
//验证输入的参数个数
try {
if(args.length != 2) {
throw new ArrayIndexOutOfBoundsException("参数个数不对");
}
//把接收到的参数转为整数
int n1 = Integer.parseInt(args[0]);
int n2 = Integer.parseInt(args[1]);
double res = cal(n1,n2);
System.out.println("计算结果是:" + res);
}catch(ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}catch(NumberFormatException e) {
System.out.println("参数格式不正确,需要输出整数");
}catch(ArithmeticException e) {
System.out.println("出现了除0的异常");
}
}
static double cal(int n1,int n2) {
double res;
return res = n1/n2;
}
}