目录
异常概述
1.概念
程序中出现的任何不正常现象
2.分类
2.1 Error (错误)
java虚拟机无法处理的不正常情况
一旦程序运行时出现错误 程序无法解决
public class ErrorDemo {
/*
Error 错误
程序运行时出现的不正常情况,无法通过程序解决
异常原因:
Exception in thread "main" java.lang.StackOverflowError
*/
public static void main(String[] args) {
ErrorDemo eooroDemo = new ErrorDemo();
eooroDemo.sum(7);
}
public int sum(int num){
return sum(num+1) + num;
}
}
2.2 Exception (异常)
程序运行出现不正常情况 可以通过异常处理机制解决 即程序可以解决
虚拟机默认的处理方式是停止运行
程序编译期间不报错 运行时出现异常
常见的几种异常:
- 数组越界异常
public static void main(String[] args) {
/*
数组越界异常
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
at ExceptionDemo.main(ExceptionDemo.java:11)
*/
int [] arr = new int[3]; //012
arr[3] = 3; //数组arr的最后一个位置为a[2]
System.out.println("aa");
- 算术异常
/*
算术异常
Exception in thread "main" java.lang.ArithmeticException: / by zero
at ExceptionDemo.main(ExceptionDemo.java:21)
*/
int a = 7;
int b = 0;
System.out.println(a/b); //除数为0 不符合算数法则
- 类型转换异常
/*
类型转换异常
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at ExceptionDemo.main(ExceptionDemo.java:29)
*/
Object obj = "abc";
Integer i = (Integer)obj; //obj为字符串
System.out.println("aaa");
- 空指针异常
/*
空指针异常
Exception in thread "main" java.lang.NullPointerException
at ExceptionDemo.main(ExceptionDemo.java:38)
*/
String s = null;
s.length();
程序运行异常格式:
异常的体系
异常处理
1. try catch组合
public class TryCatch {
public static void main(String[] args) {
/*
算术异常
后面代码
*/
try { //基础情况下的try catch
System.out.println(10/0);
}catch (ArithmeticException e){
System.out.println("算术异常");
}
System.out.println("后面代码");
/*
5
空指针异常
后面代码
*/
try {
System.out.println(10/2); //若计算10/0 则直接输出算术异常 不运行内嵌套的try catc
String s = null;
try { //嵌套try catch
System.out.println(s.length());
}catch (NullPointerException n){
System.out.println("空指针异常");
}
}catch (ArithmeticException e){
System.out.println("算数异常");
}
System.out.println("后面代码");
/*
程序忙,请稍后重试
后面代码
*/
try {
String s = "abc";
int c = 10/0;
System.out.println(s.length());
System.out.println(c);
}catch (NullPointerException n){ //多个catc
System.out.println("空指针异常");
}catch (Exception e){ //多个catch时 Exception必须在最后一个catch
System.out.println("程序忙,请稍后重试");
}
System.out.println("后面代码");
}
}
2. try catch finally组合
- try catch finally
- try finally
package trycatchfinally;
public class Demo1 {
public static void main(String[] args) {
/*
程序忙
finally
后面代码
*/
try {
System.out.println(10/0);
}catch (Exception e){
System.out.println("程序忙");
}finally {
System.out.println("finally"); //此时作用不明显
}
System.out.println("后面代码");
/*
finally
Exception in thread "main" java.lang.ArithmeticException: / by zero
at trycatchfinally.Demo1.main(Demo1.java:23)
*/
try {
System.out.println(10/0); //发生异常 但不处理 程序不能向后执行 但finally中的代码可执行
}finally {
System.out.println("finally"); //最终必须执行的代码
}
System.out.println("后面代码");
}
}
package trycatchfinally;
public class Demo2 {
/*
算术异常
finally
-1
*/
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;
}catch (ArithmeticException e){
System.out.println("算术异常"); //第一步
return -1; //第三步
}finally {
System.out.println("finally"); //第二步
}
}
}
3. throws(声明)
声明可能出现异常的代码
throws + UnsupportedEncodingException(编译期异常) ----> 提示方法调用的地方 编译器必须处理
throws + NullPointerException(运行期异常) ----> 编译器不显示的提示处理 即编译期可以不处理
3.1 基础形式
import java.io.UnsupportedEncodingException;
public class ThrowsDemo {
/*
throws + UnsupportedEncodingException(编译期异常) ----> 提示方法调用的地方 编译器必须处理
throws + NullPointerException(运行期异常) ----> 编译器不显示的提示处理 即编译期可以不处理
*/
public static void main(String[] args) {
try {
ThrowsDemo.test2(); //顶层中必须有实现 即try catch
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static void test2() throws UnsupportedEncodingException { //调用时继续抛出异常
ThrowsDemo.test1(); //调用test1
}
/*
模拟是一个偏底层的方法 这样的方法一般不try catch
继续声明此方法可能会出现异常 作为方法的声明(定义)
也就是说 用throws抛出异常 谁调用谁处理
调用时可以继续抛出 但在顶层必须有实现
*/
public static void test1() throws UnsupportedEncodingException {
String s = "abc";
s.getBytes("utf-8");
}
}
3.2 继承中的throws
package extendsthrows;
import java.io.IOException;
import java.text.ParseException;
public abstract class Father {
public abstract void test1() throws UnsupportedOperationException; //编译期异常
public abstract void test2() throws IOException; //输入输出异常
public abstract void test3() throws RuntimeException,UnsupportedOperationException; //运行期异常,编译期异常
public abstract void test4() throws NullPointerException, ParseException; //空指针异常,解析异常
}
package extendsthrows;
import java.text.ParseException;
public class Son extends Father{
/*
方法重写规则:
方法名相同,返回值类型相同,参数列表相同
访问权限 等于或大于 父类
声明异常类型 等于或小于 父类
*/
@Override
public void test1() throws UnsupportedOperationException { //声明异常类型与父类相同
}
@Override
public void test2() throws UnsupportedOperationException { //声明异常类型小于父类
}
@Override
public void test3() throws RuntimeException, UnsupportedOperationException {
}
@Override
public void test4() throws NullPointerException, ParseException {
}
}
方法重写规则: 方法名相同,返回值类型相同,参数列表相同 访问权限 等于或大于 父类 声明异常类型 等于或小于 父类
4. throw
import java.io.UnsupportedEncodingException;
public class ThrowDemo {
public static void main(String[] args) {
try {
trans(101);
} catch (UnsupportedEncodingException e) {
System.out.println(e.getMessage());
}
}
public static String trans(int socre) throws UnsupportedEncodingException {
if (socre < 0 || socre > 100){
/*
在方法中显示的抛出一个异常类的对象 表示此处实际发生了异常
new + 有参的构造方法 (参数为描述异常的原因)
*/
throw new UnsupportedEncodingException("非法分数");
}
if (socre >= 85){
return "A";
}else if (socre < 85 || socre >= 60){
return "B";
}else {
return "C";
}
}
}
5. 自定义异常
在业务开放过程中 可以根据业务需求自己开发一个异常类 表示某一类问题
package selfthrow;
public class SocreThrow extends Exception{
/*
自定义异常:在业务开放过程中 可以根据业务需求自己开发一个异常类 表示某一类问题
*/
public SocreThrow() {
}
public SocreThrow(String message) {
super(message);
}
}
package selfthrow;
public class Test {
public static void main(String[] args) {
try {
trans(101);
} catch (SocreThrow e) {
System.out.println(e.getMessage()); //获取异常原因
e.getMessage(); //都是调用父类 获取异常原因(描述)
e.printStackTrace(); //在控制台打印出详细的异常信息 在开发测试期间使用
}
}
public static String trans(int socre) throws SocreThrow {
if (socre < 0 || socre > 100){
throw new SocreThrow("非法分数"); //new+有参的构造方法 ---> 描述异常原因 ---> 目的:传递异常信息
}
if (socre >= 85){
return "A";
}else if (socre < 85 || socre >= 60){
return "B";
}else {
return "C";
}
}
}