总结
异常
异常:不正常的情况
Error
广义上的异常
运行的所有不正常情况,无法解决的问题
如:文件读写时文件删除,网路中断,内存不够 JVM系统内部错误,资源耗尽
Exception
狭义上的异常
运行时,由于程序缺陷(编程错误/外在因素) 导致的运行不正常情况,出现后程序可控制。进行处理后,继续执行。
体系
①虚拟机终止(默认)
②编译时异常 (捕获异常最理想)
将代码放在try-catch里捕获并打印异常
直接或间接继承Exception 【检查型异常】
在编译期间就强制要求处理,否则无法继续编译
IOException
SQLException
ParseException
UnsupportedEncodingException
③运行时异常
RuntimeException的子类【非检查型异常】
数学异常(除数为0),数组下标越界,空指针异常
Format
编译时不强制要求处理,程序员应该通过合理编码来努力避免程序出现这类异常
ArrayIndexOutOfBoundException
NullPointerException
处理
为程序提供了错误处理的能力
五个关键字
捕获异常:try异常代码 catch捕获异常 finally
声明异常:throw
抛出异常:throws
try后可以有多个catch,子类往父类写
-
异常对象父类-子类:Exception-RuntimeException-其他
-
e.printStackTrace(); //开发期间调试程序,打印异常信息现实中使用一些日志组件将信息输出到日志文件中
-
System.out.println(e.getMessage()); //获得异常原因/ by zero
package javaException;
public class ExceptionDemo1 {
public static void main(String[] args) {
/*
try{
可能出现异常的代码
}catch(异常类型 e 用来接收抛出异常的对象){
捕获处理发生的异常
}
后续程序继续执行
*/
while (true){
try{
int a=10;
int b=0;
int c=a/b;
System.out.println(c);
}catch (ArithmeticException e){ //runtimeException Exception是所有异常父类
System.out.println(e);
//e.printStackTrace(); //开发期间调试程序,打印异常信息 java.lang.ArithmeticException
//现实中使用一些日志组件将信息输出到日志文件中
System.out.println(e.getMessage()); //获得异常原因/ by zero
System.out.println("运算错误"); //运算错误
}
System.out.println("aaaaaaaaaaaaaa"); //aaaaaaaaaaaaaa
}
}
}
try-catch多种写法
- trycatch嵌套
- 一个try多个catch
只要看到异常,catch就会捕获,后续程序继续执行。不会管其他异常。 - 大的异常对象类型必须写在子类类型下面
package javaException;
public class ExceptionDemo2 {
public static void main(String[] args) {
/*
try{
可能出现异常的代码
}catch(异常类型 e){
捕获处理发生的异常
}
后续程序继续执行
*/
while (true){
try{
int a=10;
int b=2;
int c=a/b;
System.out.println(c);
try {
String s=null;
System.out.println(s.length());
} catch (NullPointerException e) {
System.out.println("对象为空");
}
System.out.println("bbbb");
}catch (ArithmeticException e){ //runtimeException Exception是所有异常父类
System.out.println(e);
//e.printStackTrace(); //开发期间调试程序,打印异常信息 java.lang.ArithmeticException
//现实中使用一些日志组件将信息输出到日志文件中
System.out.println(e.getMessage()); //获得异常原因/ by zero
System.out.println("运算错误"); //运算错误
}
System.out.println("aaaaaaaaaaaaaa"); //aaaaaaaaaaaaaa
//只执行对象为空aaaa
}
}
}
package javaException;
public class ExceptionDemo3 {
public static void main(String[] args) {
/*
try{
可能出现异常的代码
}catch(异常类型 e){
捕获处理发生的异常
}
后续程序继续执行
*/
while (true){
try{
//"abc".charAt(4); //出现异常 catch捕获不到 直接报错
int a=10;
int b=0;
int c=a/b;
System.out.println(c);
String s=null;
System.out.println(s.length());
System.out.println("bbbb");
}catch (ArithmeticException e){ //runtimeException Exception是所有异常父类
System.out.println(e);
//e.printStackTrace(); //开发期间调试程序,打印异常信息 java.lang.ArithmeticException
//现实中使用一些日志组件将信息输出到日志文件中
System.out.println(e.getMessage()); //获得异常原因/ by zero
System.out.println("运算错误"); //运算错误
}catch (NullPointerException n){ //捕获与本catch类型相同的异常
System.out.println("对象为空");
}catch (Exception e){
System.out.println("出错啦");
}
System.out.println("aaaaaaaaaaaaaa"); //aaaaaaaaaaaaaa
//只执行运算错误aaaaa
//大的类型必须写在子类类型下面
}
}
}
finally
- 即使异常了 也会执行finally代码块
- try+finally 一旦出现异常,会执行fianlly,之后程序崩掉了
package javaException;
public class ExcepFinally {
/*
try{
可能出现异常的代码
}catch(异常类型 e){
捕获处理发生的异常
}finally{
无论是否出现异常,代码都会执行
}
后续程序继续执行
*/
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
try{
int a=10;
int b=0;
int c=a/b;
return c;
//System.out.println(c);
//System.out.println("bbbb");
}catch (ArithmeticException e){ //runtimeException Exception是所有异常父类
System.out.println("运算错误"); //运算错误
return -1; //即使异常了 也会执行finally代码块
}finally {
System.out.println("ccccccc"); //IO jdbc
return 0;
}
//System.out.println("aaaaaaaaaaaaaa"); //aaaaaaaaaaaaaa
//有异常 执行aaaa。不会执行bbb了。
//需要finally 执行cccc aaaaa
//运算错误
//ccccccc
//0
}
}
package javaException;
public class ExcepFinally2 {
public static void main(String[] args) {
test();
}
public static void test(){
try{
int a=10;
int b=0;
int c=a/b;
//System.out.println(c);
//System.out.println("bbbb");
}finally { //try+finally 一旦出现异常,会执行fianlly,之后程序崩掉了
System.out.println("ccccccc"); //IO jdbc
}
System.out.println("aaaaaa");
//ccccccc
//Exception in thread "main" java.lang.ArithmeticException: / by zero
// at javaException.ExcepFinally2.test(ExcepFinally2.java:12)
// at javaException.ExcepFinally2.main(ExcepFinally2.java:5)
}
}
throws编译异常
-
定义一个方法可以使用throws关键字声明,表示此方法 不处理异常,而交给方法调用处进行处理
public void
test throws 异常1,异常2,异常3{ }
-
throws NullPointerException 运行时异常,方法调用处可以处理也可以不处理
UnsupportedEncodingException 编译期异常,调用在编译期间必须处理 -
一般情况下,throws后面一般都声明是编译期异常
一般位于底层的方法都选择向上声明抛出 -
使用了throws的方法,调用时必须处理声明的异常,要么使用try-catch
-
抽象方法。 子类重写父类中的方法,声明的异常必须小于或等于父类声明的异常
package javaException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Excepthrow {
public static void main(String[] args){
try{
test1();
}catch (UnsupportedEncodingException e){
System.out.println("编码不支持");
}catch (NullPointerException e){
System.out.println("字符为空");
}catch (ParseException e){
System.out.println("日期解析异常");
}
System.out.println("aaaaaaaaaaaaaa");
}
public static void test1() throws UnsupportedEncodingException, ParseException {
test2();
}
public static void test2() throws UnsupportedEncodingException, ParseException {
test3(); //Add exception to method signature 抛出异常
}
/*
throws NullPointerException 运行时异常 声明为运行时异常,方法调用处可以处理也可以不处理
UnsupportedEncodingException 声明为编译期异常,那么调用在编译期间必须处理
一般情况下,throws后面一般都声明是编译期异常
一般位于底层的方法都选择向上声明抛出
*/
public static void test3() throws NullPointerException, UnsupportedEncodingException, ParseException {
String s="中国";
s.getBytes("gbk");
SimpleDateFormat sdf=new SimpleDateFormat("");
sdf.parse("");
//日期解析异常
//aaaaaaaaaaaaaa
}
}
package javaException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
public abstract class Excepthrows2 {
//抽象方法无方法体
public abstract void eat() throws Exception;
}
package javaException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
public class ExcepthrowsDemo extends Excepthrows2{
//抽象方法继承需要重写父类方法
//返回值,方法名,参数必须一样 访问权限修饰符 大于等于父类方法权限
//声明的异常必须小于或等于父类声明的异常
@Override
public void eat() throws UnsupportedEncodingException, ParseException {
}
}
throw异常对象
显式抛出异常,抛出的时候是抛出的是一个异常类的实例化对象
throw throw new 异常类构造方法
package javaException;
public class throwdemo {
public static void main(String[] args) {
//System.out.println(10/0); //由虚拟机在运行时出现的异常,抛出一个此类的对象
/*
Exception in thread "main" java.lang.ArithmeticException: / by zero
at javaException.throwdemo.main(throwdemo.java:5)
*/
try {
subFileType(null);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public static String subFileType(String fileName){
if(fileName!=null){
//在一个对应的异常对象方法体中,主动显示的抛出一个对应的异常对象,告知(通知)方法调用处,传入的数据有问题
throw new NullPointerException("文件名为空");
}
return fileName.substring(fileName.lastIndexOf(".")+1);
}
}
throw和throws区别
throws: 方法声明处,抽象方法也可
throw: 方法体,用来抛出实际异常对象
自定义异常
自己定义的异常类,也就是API中的标准异常类的直接或间接的Exception子类
● 作用:用自定义异常标记业务逻辑的异常,避免与标准异常混淆
ScoreException
package javaException;
public class ScoreException extends Exception{
/*
自定义异常类
分数异常类
*/
public ScoreException() {
super();
}
public ScoreException(String msg) {
super(msg);
}
}
ScoreTest
package javaException;
public class ScoreTest {
public static void main(String[] args) {
try {
score(-10);
} catch (ScoreException e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public static String score(double score) throws ScoreException {
if(score<0){
throw new ScoreException("分数小于0了");
}
if(score>100){
throw new ScoreException("分数大于100了");
}
if(score>=90){
return "A";
}
return "D";
}
}