文章目录
异常
1、什么是异常?
从广义上讲,异常指一切不正常情况 包括Error Exception
java 中把不正常情况分为:
Error错误: 指的是通过程序无法解决的,例如: 内存不够用了,堆溢出 JVM崩了…
Exception异常(狭义): 例如:栈溢出 算数异常、数组越界、数字格式化、空指正、类型转换…
2、异常的体系 (Throwable)
java.lang**.Throwable** : 两个直接子类 java.lang.Error java.lang.Excepetion
Exception 分为两大类:
1)运行异常 Runtime Exception,编译时可以不处理,根据经验判断
2)检查异常 Checked Exception ,编译期异常,写代码时被强制处理
3、怎么解决异常?
对于异常,一般有两种解决方法:
-
一是遇到异常就终止程序的运行。
-
二是由程序员在编写时,就考虑到异常的检测、异常消息的提示,以及异常的处理
捕获异常最理想是在编译期,但是有的异常只有在运行时才发生。
分类:编译时异常 、 运行时异常
在编写代码时, 预计程序中可能出现的问题,针对问题进行捕获处理
程序正常执行,如果没有问题, 按照正常的流程执行,如果有异常,按照事先定义的处理流程执行。
try{
//可能出现异常的代码
}catch( 异常类型 a){
//处理对应类型的异常
}
try{
//可能出现异常的代码
}catch( 异常类型 a){
//处理对应类型的异常
//可以有多个catch
}finally{
//将必须要执行的逻辑写到finally代码块中
//此代码块内容一定会执行,即使出现异常
//只能有一个finally
}
try{
}finally{
}
//出现异常,执行必须执行的逻辑
异常处理关键字:5个 try、catch、finally、throw、throws
Error 错误 和 Exception 异常
package com.ffyc.javaexception;
public class Demo1 {
public static void main(String[] args) {
/*
//Error 错误
int [] a = new int[Integer.MAX_VALUE];//堆溢出
*/
//Expecetion 异常
Demo1.test(); //栈溢出
}
public static void test(){
test();
}
}
package com.ffyc.javaexception;
public class ExpecetionDemo {
/*
异常案例
*/
public static void main(String[] args) {
// int a =10;
// int b = 0 ;
// System.out.println(a/b); //算数异常
// System.out.println("后面的代码");
/* java中把语法中会出现的问题,都包装成一个类,当程序中出现此类问题时,就抛出此类对象
Arithmeticexception:异常类型(何种语法情况下出现)by zero:算数异常 异常原因
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.ffyc.javaexception.ExpecetionDemo.main(ExpecetionDemo.java:12) 异常位置
java默认情况下,如果出现了异常,那么就简单粗暴的抛出异常信息,然后终止程序运行。
*/
// int [] a = new int[5];
// a[5] = 10;
/* 数组越界
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at com.ffyc.javaexception.ExpecetionDemo.main(ExpecetionDemo.java:23)
*/
// Object s =100 ;
// String s1 = (String)s;
/* 类转换异常
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at com.ffyc.javaexception.ExpecetionDemo.main(ExpecetionDemo.java:30)
*/
// String s = null;
// s.length();
/* 空指针异常
Exception in thread "main" java.lang.NullPointerException
at com.ffyc.javaexception.ExpecetionDemo.main(ExpecetionDemo.java:37)
*/
Integer a = new Integer("1a0");
/* 数字个格式化异常
Exception in thread "main" java.lang.NumberFormatException: For input string: "1a0"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.<init>(Integer.java:867)
at com.ffyc.javaexception.ExpecetionDemo.main(ExpecetionDemo.java:43)
*/
}
}
try catch
package com.ffyc.javaexception;
public class Demo3 {
public static void main(String[] args) {
/*
try{
可能出现异常的代码
}catch(具体的异常类型 形参){
对异常的处理
}
一个try 可以对应多个catch,每个catch对应一个异常类型
大的类型的catch写到下面
*/
int a = 10;
int b = 0 ;
try{
int c = a/b;
String s = null;
s.length();
new Integer(a); // NumberFormatException
}catch ( ArithmeticException ae ) { //捕获算数异常
System.out.println("算术运算符");
}catch ( NullPointerException ne ){ //捕获 空指针异常
System.out.println("对象不能为空");
}catch ( Exception e ){ //如果不确定还有什么异常,可以扩大异常范围, 多态
e.printStackTrace(); // 开发期间使用此方法向控制台打印输出日志信息,后期通过日志组件输出信息到文件中
System.out.println(e.getMessage());
System.out.println("系统忙,请稍后再试!");
}
System.out.println("后面的程序继续执行");
}
}
try catch finally
package com.ffyc.javaexception;
import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
public class Demo4 {
public static void main(String[] args) {
/*
try catch finally
*/
/*
try{
System.out.println(10/0);
}catch(Exception e ){
System.out.println("程序出错了");
}finally {
System.out.println("关闭连接");
}
System.out.println("后面的代码");
*/
System.out.println( Demo4.test(10, 0));
}
public static int test(int a ,int b){
try{
int c =a/b;
return c;
}catch (Exception e){
System.out.println("程序出错了");
return -1;//假设出现异常返回-1
}finally {
System.out.println("关闭连接");
}
}//程序出错了 关闭连接 -1
}
try finally
try{
}finally{
}
//出现异常,执行必须执行的逻辑
throws 声明异常
- 声明方法,表示此方法不处理异常,而是交给方法调用处进行处理
例如:public void test throws 异常1 ,异常2,异常3…{
}
-
任何方法都可以使用throws关键字声明异常类型,包括抽象方法。
-
子类重写父类中的方法,子类方法不能声明抛出比父类类型更大的异常(针对编译期异常)
-
使用throws的方法,调用时必须处理声明的异常,要么使用 try -catch ,妖魔继续使用throws声明
package com.ffyc.javaexception;
import java.io.UnsupportedEncodingException;
public class Demo5 {
public static void main(String[] args) {
try {
Demo5.test1();
System.out.println("sssss");
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
}
//一般在底层不处理异常,声明异常,抛出,在高层处理异常
public static void test1()throws UnsupportedEncodingException {
System.out.println("test1");
Demo5.test2();
}
/*
throws 是在方法的声明处,声明此方法可能会出现某种异常类型
如果抛出的是 throws ArithmeticException 算数异常 ,是运行时异常,那么调用的地方可以处理,也可以不处理
UnsupportedEncodingException 时属于编译期异常(检查异常),那么谁调用此方法,必须在编译期间就进行处理(try catch throws)
*/
public static void test2() throws ArithmeticException {
System.out.println("test2");
try {
"abc".getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
System.out.println(10/0);
}
}
throw 抛出异常
异常:父类实现异常、子类定义
接口:父类定义接口,子类实现
throw: 在程序中主动抛出异常对象,表示此方法出现了某种异常
package com.ffyc.javaexception;
public class Demo7 {
public static void main(String[] args) {
try{
checkScore(118);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
public static char checkScore(int score) throws Exception {
if(score <0||score > 90){
//主动在程序中使用throw关键字 抛出一个异常对象
throw new Exception("无效成绩");
}
if(score >= 90){
return 'A';
}else{
return 'B';
}
}
}
自定义异常
- 就是自己定义的异常类
- 也就是API中标准异常类的直接或间接子类
- 作用: 用自定义异常标记业务逻辑的异常,避免与标准异常混淆
package com.ffyc.javaexception;
public class ScoreException extends Exception {
/*
自定义异常:
主要是对程序中的业务逻辑出现不满足情况时输出
当不满足百分制输出时输出此类对象
*/
public ScoreException (String message){
super(message);
}
}
package com.ffyc.javaexception;
public class Demo7 {
public static void main(String[] args) {
try{
checkScore(118);
}catch (ScoreException e){
System.out.println(e.getMessage());
}
}
public static char checkScore(int score) throws ScoreException{
if(score <0||score > 90){
//主动在程序中使用throw关键字 抛出一个异常对象
throw new ScoreException("无效成绩");
}
if(score >= 90){
return 'A';
}else{
return 'B';
}
}
}