异常(Exception)
基本概念:程序执行过程中发生不正常的情况成为”异常“。(开发过程中语法错误,或逻辑错误不是异常。
执行过程中所发生的有两大类异常:
1、Error(错误):java虚拟机无法解决的严重问题。如:JVM系统内部错误,资源耗尽等问题。比如:StackOverflowError[栈溢出】和OOM(out of
menory)内存不足,Error是严重错误,程序会崩溃。
2、Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以针对性对代码进行处理。例如空指针访问,试图读出不存在的文件,网络连接中断等等,
Exception分为两大类:运行时异常[程序运行时]和编译时[编译时侯]异常
异常体系图:
异常小结:
1、异常分为两大类,运行时异常和编译时异常
2、运行时异常,有默认处理机制,编译器不要求强制处置的异常。一般指编程中的逻辑错误,是程序员应该避免的异常。java.lang.RuntimeException类及它的子类都是运行时异常
3、对于运行时异常可以不做处理,因为这些异常很普遍,如果全部处理可能会对程序的可读性和运行效率有影响(会有很多try-catch)。
4、编译时异常(文件或者是类.class找不到)是必须处理的异常
package com.hsp.exception;
/**
* @version 1.0
* @Author Cxc
*/
public class Exception01 {
public static void main(String[] args) {
int num1=2;
int num2=0;
//int res = num1/num2;//分母为零,程序就会出现(抛出)异常,程序就退出了,崩溃了,下面的代码就不再执行
//如果程序员,认为一段代码可能出现异常/问题,可以使用try-catch异常处理机制来解决,从而保证程序的健壮性
try {
int res = num1/num2;
} catch (Exception e) {
e.printStackTrace();
System.out.println("出现异常的原因:"+e.getMessage());//输出异常信息
}
//快捷键:选中要处理代码块ctrl+alt+t,即使出现了异常,也能继续执行
System.out.println("程序继续运行。。");
//不应该出现一个不算致命的问题,就导致整个系统崩溃,因此提供异常处理机制解决
}
}
常见运行时异常:
(1)NullPointerException空指针异常
需要对象的地方使用null,抛出异常。
package com.hsp.exception;
/**
* @version 1.0
* @Author Cxc
*/
@SuppressWarnings({"all"})
public class NullException {
public static void main(String[] args) {
String name=null;
System.out.println(name.length());
}
}
(2)ArithmeticException数学运算异常
当出现异常条件时抛出异常。如分母为零
(3)ArrayIndexOutOfBoundsException数组下标越界异常
用非法索引访问数组时抛出异常,如索引为负数,或者大于等于数组大小
package com.hsp.exception;
/**
* @version 1.0
* @Author Cxc
*/
public class ArrayIndexOutOfBoundsException_ {
public static void main(String[] args) {
int[] arr = {1,2,3};
for(int i = 0; i<= arr.length; i++){
System.out.println(arr[i]);
}
}
}
(4)ClassCastException类型转换异常
当试图将对象强制转换为不是实例的的子类时,抛出异常。
package com.hsp.exception;
/**
* @version 1.0
* @Author Cxc
*/
public class ClassCastException_ {
public static void main(String[] args) {
A b = new B();//向上转型
B b2 = (B)b;//向下转型
C c2 = (C)b;//错误,B、C类没关系,这了就会抛出ClassCastException
}
}
class A{}
class B extends A{}
class C extends A{}
(5)NumberFormatException数字格式不正确异常
当应用程序试图将字符串转换成一种数值类型,但字符串不能转换成适当格式时,抛出异常
package com.hsp.exception;
/**
* @version 1.0
* @Author Cxc
*/
public class NumberFormatException_ {
public static void main(String[] args) {
String name = "张三";
int num = Integer.parseInt(name);
System.out.println(num);
}
}
编译异常:
编译异常是编译期间必须处理的异常,否则代码不能通过编译
常见的编译异常:
SQLException//操作数据库时,查询表可能出现的异常
IOException//操作文件时,发生的异常
FileNotFoundException//操作不存在文件时发生的异常
ClassNotFoundException//加载类,而该类不存在时异常
EOFException//操作文件载文件末尾发生异常
IllegalArgumentException//参数异常
异常处理:
异常处理方式:
(1)try-catch-finally
程序员在代码中捕获发生的异常,自行处理
try{
代码/可能有异常
}catch(Exception e){
//捕获到异常
//1、当异常发生时,系统将异常封装成Exxeption对象e,传递给catch
//2、得到异常后,程序员可以自己处理
//3、注意:如果没有发生异常,catch代码块不执行
}finally{
//不管try代码块有没有异常发生,始终要执行finally
//通常将释放资源代码放在这里
}
(2)throws
将发生的异常抛出,交给调用者(方法)处理,最顶级的处理者是JVM
1、try-catch-finally和throws二选一
2、如果程序员没有处理异常,默认throws
public void f1() throws FileNotFoundException {
//FileNotFoundException编译类异常 throws抛给调用者去处理
//throws可以是方法中异常FileNotFoundException,也可以是父类异常Exception.
//throws关键字也可以是异常列表 ,抛出多个异常
FileInputStream fileInputStream = new FileInputStream("://aa.text");
}
try- catch异常处理细节
(1)如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块
(2)如果异常没有发生,则顺序执行try,不会进入catch
(3) 如果不管发生什么,都要执行代码块,(如:关闭连接,释放资源等)则使用finally{}
(4) 可以有多个catch语句,捕获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,
比如(Exception在后,NullPointerException在前)如果发生异常只会匹配一个catch,如下
package com.hsp.try_;
/**
* @version 1.0
* @Author Cxc
*/
public class TryCatch02 {
public static void main(String[] args) {
try {
Person person = new Person();
person = null;
System.out.println(person.getName());
int num1 =2;
int num2 = 0;
int res = num1/num2;
} catch (NullPointerException e){
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println("错误信息"+ e.getMessage());
}
}
}
class Person{
private String name ="tom";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
(5)可以进行try-finally配合使用,这种用法相当于没有捕获异常,因此程序直接崩掉。应用场景:执行一段代码,不管法神什么异常,都必须执行某个业务逻辑。
try {
int num1 =2;
int num2 = 0;
int res = num1/num2;
} finally {
System.out.println("finally");
}
(6)子类重写父类的方法时,对抛出异常的规定:子类重写的方法,
所抛出的异常要么和父类抛出的异常一致,要么是父类抛出异常的子类
自定义异常:
(1)定义类:自定义异常类名(程序元自己写)继承Exception或RuntimeException
(2) 如果继承exception,属于编译异常
(3)如果继承RuntimeException,属于运行异常
public class CustomException {
public static void main(String[] args) {
int age =120;
if(!(age>18&&age<80)){
throw new AgeException("年龄需要在18-80");
}
System.out.println("你的年龄正确");
}
}
//自定义异常
class AgeException extends RuntimeException{
public AgeException(String message) {
super(message);
}
}