异常概念
-
在java语言中,程序运行中发生的不正常的情况称为异常
-
java语言中在执行过程中所发生的异常可以分成两类
-
Error:java虚拟机无法解决的问题,例如:jvm系统内部错误、资源耗尽等严重情况。一般编写针对性的代码进行处理。
-
Exception:由于代码的编程错误或者其他的一些外部偶然性因素导致的一般性问题,可以编写针对性的代码进行处理。例如:
-
访问数组下标越界
-
试图读取不存在的文件
-
网络连接中断
-
-
java异常的分类
-
编译期异常:编译期间程序就要求要处理此类问题
-
运行时异常:编译期间是好的,但是运行期间出现了问题
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException { /*
java中如果出现了异常,虚拟默认抛出对应语法问题的类的对象.
*/
//1.算术异常 ArithmeticException
//System.out.println(10/0);
//2.数组越界 ArrayIndexOutOfBoundsException
//int[] a ={1,2,3,4,5};
//a[5] =6;
//3.数字格式化 NumberFormatException
//int a = Integer.parseInt("a10");
//4.空指针 使用值为null的引用 NullPointerException
//String s =null;
//s.getBytes();
//5.类型转换异常 ClassCastException
//Object a ="abc";
//Integer b =(Integer)a;
//ClassNotFoundException 编译期间异常 写代码时就强制要求处理 //Class.forName("FF.DEMO");
System.out.println("aaaaaaaaaaaa"); }}
由上可见,1-5的类型都是运行期间的异常,而最后的一个就是编译期异常,当然编译期异常还有很多,在此我们就不多做举例了
java的体系
java体系中:
在java.lang.throwable中有两个直接子类
-
java.lang.Error:表示错误,程序无法处理
-
java.lang.Exception:表示异常,可以用程序来处理
异常处理
try catch语句
-
try:检测不安全的代码块(发现异常)
try块中任何一条语句发生了异常,下面的代码都不会执行,程序会直接跳转到异常处理的代码块中,也就是catch块。所以,不能将不相关的代码放到try语句块中,因此可能会随时终止运行。
-
catch:把抓到的类型匹配的异常捕获,保证程序可以正常的运行下去
catch语句必须紧跟try语句,称为捕获异常
public class Demo3 {
public static void main(String[] args) {
/*
try{
写可能会出现异常的代码
}catch(捕获的异常类型){
处理方案 }
....... */
int a =10;
int b =0;
try {
int c = a / b;
System.out.println("bbbbbbbbbbbb");//不会运行
}catch (ArithmeticException e){
e.printStackTrace();//向控制台打印异常信息,便于开发期间调试 System.out.println(e.getMessage());//获取异常原因 System.out.println("非法算术运算"); } System.out.println("aaaaaaaaaaaa"); }}
一个try后面可以写多个catch,用来捕获多个不同类型的异常
public class Demo4 {
public static void main(String[] args) {
/* try{
写可能会出现异常的代码
}catch(捕获的异常类型){
处理方案 }
....... */
int a =10;
int b =2;
try {
int c = a / b;
System.out.println("bbbbbbbbbbbb");//不会运行
String s ="null";
s.length();
int d =Integer.parseInt("a");
}catch (ArithmeticException e){
System.out.println("非法算术运算");
}catch (NullPointerException n){
System.out.println("对象为空");
}catch (Exception ex){
System.out.println("系统繁忙!"); } System.out.println("aaaaaaaaaaaa"); }}
如果int b =2;那么 System.out.println("bbbbbbbbbbbb");就会运行
如果int b =0;那么System.out.println("bbbbbbbbbbbb");//不会运行
finally语句
finally语句中的内容总会执行,只能有一个finally语句
finally{
必须执行的逻辑
}
public class Demo5 {
public static void main(String[] args) {
/*try {
test1();
}catch (Exception e) {
}finally{
无论是否出现异常,finally中的代码都会执行
}*/
int res=test2(10, 0);
System.out.println(res); }
private static int test2(int a,int b) {
try{
int c =a/b;
return c;
}catch (Exception e){
return -1;
}finally {
System.out.println("finally 代码块");//IO 数据库 } }
private static void test1() {
try{
System.out.println(10/0);
}finally {
System.out.println("finally 代码块");//IO 数据库 }
System.out.println("aaaaaaaaaaaaaa"); }}
throws关键字
定义一个方法的时候可以使用throws关键字声明,表示此方法不处理异常,而交给方法调用处进行处理
import java.io.UnsupportedEncodingException;
public class Demo6 {
public static void main(String[] args) {
try {
test1();
} catch (UnsupportedEncodingException e) { e.printStackTrace();
System.out.println("不支持的编码格式");
} }
private static void test1() throws UnsupportedEncodingException { test2();//谁调用谁处理 }
/*
throws 在方法的形参列表后面,声明此方法可能会抛出某种类型的异常,可以声明多个 如果声明为运行时异常,编译期间不强制处理
如果声明为编译期异常,编译期间强制提示进行处理 */
private static void test2() throws UnsupportedEncodingException { "abc".getBytes("utf-8"); }}
任何方法都可以使用throws关键字声明异常类型,包括抽象方法.
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public abstract class P {
abstract void test1()throws UnsupportedEncodingException;
public abstract void test2()throws IOException;
public abstract void test3()throws NullPointerException;//运行期异常,编译期不反应}
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class C extends P{
/*
方法重写:
方法名相同
参数列表相同
返回值类型相同
访问权限等于,大于父类声明的权限
声明的异常类型等于或小于父类声明的异常(针对编译期异常)
*/
@Override
public void test1() throws UnsupportedEncodingException {
}
@Override
public void test2() throws IOException {
}
@Override
public void test3() throws RuntimeException {
}
}
-
子类重写的方法不能声明抛出比父类大的异常
-
由以上代码我们可以看出 这个规则只是针对编译期异常
-
比如test3()方法,由于其是运行期异常 所以就不会报错
-
-
使用了throws的方法,调用处必须处理声明的异常,要么使用try-catch,要么继续使用throws声明
-
throws后面可以跟多个异常名,用逗号隔开
throw关键字、自定义异常
-
用于显示抛出的异常,抛出的时候是抛出一个异常类的实例化对象
-
用于方法体中,用来抛出一个实际的异常对象,使用throw后,要么使用try-catch捕获异常,要么使用throws声明异常
import java.io.UnsupportedEncodingException; public class Demo7 { public static void main(String[] args) { try { test(101); } catch (ScoreException e) { e.printStackTrace(); System.out.println(e.getMessage()); } } public static char test(int score) throws ScoreException { if(score<0||score>100){ //不合法分数,没必要继续向下执行,此处可以使用throw直接在方法中抛出一个异常对象. throw new ScoreException("不合法的分数"); } if (score >= 90) { return 'A'; } else { return 'B'; } } } public class ScoreException extends Exception{ /* 我们可以根据自己的业务需要,开发自定义异常类 */ public ScoreException() { super(); } public ScoreException(String message) { super(message); } }
-
自定义异常是根据自己的需要,自己定义的一个异常
-
自定义异常往往不写其他方法,只重载需要使用的构造方法
-
继承Exception后,需要在try-catch或throws中抛出