1.异常
1.1异常的概述
概述:程序的不正常执行
处理异常的必要性:如果不处理,程序则会中断异常的分类:
Throwable:错误与异常的父类,子类有Error,Exception
Error: 错误异常,例如硬件问题,JVM异常,程序员无法处理
Exception:一般性异常,程序员能处理,包含两个子类:运行时和编译时异常
运行时异常:非受检异常,运行时出现问题,直接奔溃
例如:类型转换异常,下标越界,空指针异常,算数异常,输入不匹配异常,数字格式异常
编译时异常:受检异常, 编译时报错,需要再一次处理
1.2.运行时异常
public class RuntimeTest {
public static void main(String[] args) {
//运行时异常:
Object o = "ss"; //向上转
//Integer a = (Integer)o; //向下转 类型转换异常 ClassCaseException
int[] a= {1,2};
//System.out.println(a[2]); //下标越界ArrayIndexOutOfBoundsException
String s = null;
//System.out.println(s.length()); //空指针异常NullPointerException
//int i=1/0; //ArithmeticException算数异常
Scanner sc = new Scanner(System.in);
//int num = sc.nextInt(); //输入不匹配异常InputMismatchException
String ss = "abc";
//int aa = Integer.parseInt(ss); //数字格式异常NumberFormatException
if(true) { //加个逻辑判断,后面的代码就可到达
throw new RuntimeException("手动抛出运行时异常");//已经出错了,后面不能有代码,奔溃
//return; //正常结束,跳出函数体; 后面都不能有代码
}
System.out.println("最后的执行。。。");
}
}
1.3.编译时异常
//编译时异常: 编译时不通过,让你给出处理方案
//解决方案: 抛出,当前方法中不处理,提交给上一级去处理,如果上级也不处理,直接奔溃
public class CheckTest {
public static void main(String[] args) throws FileNotFoundException, ParseException {
//编译时异常:
//FileNotFoundException: 文件找不到异常
FileInputStream fis = new FileInputStream("a.txt");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String strDate="2108-09-09";
//ParseException:解析异常
System.out.println(sdf.parse(strDate));
}
}
2.异常传递
2.1运行时异常传递
=====================运行时异常传递==========================
//异常的传递:当方法的多级调用出现异常的情况
//运行时异常传递:
//结论:多级调用时,出现异常,则会向上传递,如果每个层次都没有处理,则会奔溃
public class Test1 {
public static void main(String[] args) {
a();
System.out.println("执行最后...");
}
private static void a() {
System.out.println("a的调用");
b();
}
private static void b() {
System.out.println("b的调用");
Scanner sc = new Scanner(System.in);
int num = sc.nextInt(); //如果我们输入字符串,则会提示输入不匹配异常
}
}
2.2编译时异常传递
=====================编译时异常传递==========================
//编译时异常的传递:
public class Test2 {
public static void main(String[] args) throws FileNotFoundException {
a();
System.out.println("执行最后...");
}
private static void a() throws FileNotFoundException {
System.out.println("a的调用");
b();
}
//throws FileNotFoundException:抛出异常,当前方法不处理,抛给上一级
private static void b() throws FileNotFoundException {
System.out.println("b的调用");
FileInputStream fis = new FileInputStream("b.txt");
}
}
3.异常处理
3.1运行时异常处理
=====================运行时异常处理==========================
//1.运行时异常的处理: 捕获异常
//捕获:隔离异常,使得后续的程序正常执行
/*
try{
//视图抓取有异常的代码..
}catch(Exception e) //有问题则捕获--隔离了
//打印异常
*/
public class Test1 {
public static void main(String[] args) {
try {
int i=1/0;
}catch(NullPointerException e) {
System.out.println("空指针异常..");
e.printStackTrace();
}catch (ArithmeticException e) { //捕获并隔离了,异常解决了
System.out.println("算数异常..");
//e.printStackTrace();
}
System.out.println("执行最后代码...");
}
}
3.2编译时异常处理
=====================编译时异常处理==========================
//编译时异常的处理:
//1.抛出:弃之不管,抛给上一级,之前案例已说明
//2.捕获:隔离异常,使得后续的程序正常执行
public class Test2 {
public static void main(String[] args) {
try {
FileInputStream fis= new FileInputStream("b.txt");
} /*catch (FileNotFoundException e) {
System.out.println("文件未找到异常");
}*/catch (Exception e) { //父类的捕获只能放后面,如果子类异常没有捕获到,那么父类一定会捕获
System.out.println("父类捕获异常..");
}
System.out.println("最后的执行。。。");
}
}
3.3传递中的异常处理
====================传递中的异常处理=====================
//传递中的异常处理:
//1.在方法实现中的捕获,在方法捕获后面的代码不受影响
//2.在main方法中的捕获,仅仅只是main方法后面不会受影响
public class Test3 {
public static void main(String[] args) {
try {
a(); //上一级的捕获
} catch (FileNotFoundException e) {
System.out.println("main方法中,文件未发现异常");
}
System.out.println("main方法后面不会受影响");
}
private static void a() throws FileNotFoundException {
/*
try {
FileInputStream fis = new FileInputStream("b.txt");
} catch (FileNotFoundException e) {
System.out.println("文件未发现异常");
}*/
FileInputStream fis = new FileInputStream("b.txt");
System.out.println("a方法实现中的执行...");
}
}
4.finally的使用
finally:最终的,搭配try或try.catch去使用的
结论:不论能否捕获住,最终都会执行finally中的代码
finay的优先级非常高,甚至比return还要高
public class Test1 {
public static void main(String[] args) {
try {
int i=1/0;
} /*catch (NullPointerException e) {
System.out.println("空指针异常");
}*/
catch (ArithmeticException e) {
System.out.println("算数异常..");
return; //跳出函数体
}finally {
System.out.println("最终要执行的");
}
System.out.println("最后的代码...");
}
}
=====================tryfinally使用==========================
//finally的用法:
//当程序是死循环时,后面是不能执行代码的,但是我们可以使用tryfinally,
//将后续要执行的代码放到finally中即可
//finally应用场景:
//io流的关闭资源,数据库资源关闭,锁资源释放
public class Test2 {
public static void main(String[] args) {
try {
while(true) {
System.out.println("一直执行的...");
}
} finally {
System.out.println("最后执行的...");
}
}
}
5.自定义异常
5.1自定义异常案例
====================自定义异常案例=====================
//自定义异常: 抛出单个对象,往往用在自定义异常中
//一般项目中可以根据需求设定异常类继承Exception或RuntimeException
//案例:录入学生的姓名和年龄,姓名要求小于6个长度,年龄小于50岁
//分析:编写学生校验的异常类继承Exception
//捕获与抛出的应用场景:
//抛出:程序的异常影响很大用抛出,例如银行金额账户等数据异常
//捕获:程序的异常影响不大用捕获,例如:上传一张图片,不符合规格
class StudentException extends Exception{
public StudentException(String msg) {
super(msg); //将学生检测异常提示传给父类
}
}
class Student{
private String name; //封装性
private int age;
public void setName(String name) throws StudentException {
if(name.length()<6) {
this.name = name;
}else {
//抛出单个对象,往往用在自定义异常中
throw new StudentException("姓名长度必须小于6");
}
}
public void setAge(int age) throws StudentException {
if(age<50) {
this.age = age;
}else {
throw new StudentException("年龄必须小于50岁");
}
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class Test1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Student st = new Student();
System.out.print("请输入学生姓名:");
String name = sc.next();
try {
st.setName(name);
} catch (StudentException e) {
e.printStackTrace();
}
System.out.print("请输入学生年龄:");
int age = sc.nextInt();
try {
st.setAge(age);
} catch (StudentException e) {
e.printStackTrace();
}
System.out.println("姓名:"+st.getName()+";年龄:"+st.getAge());
}
}
5.2异常中的重写
==================异常中的重写===================
//声明异常中的重写:
//1.满足之前重写的要求:返回值类型,方法名,参数类型和父类完全一致,权限大于等于父类
//2.再加入异常声明
//注意:子类声明的异常不能大于父类
class Super{
public void eat() throws NullPointerException {
}
}
class Son extends Super{
@Override
public void eat() throws NullPointerException /*Exception*/ {
}
}