Java15:异常处理

发布时间:2024年01月12日

1.异常概述与异常体系结构

在使用计算机语言进行项目开发的过程中,即使程序员把代码写的尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码就可以避免的。比如:客户输入数据的格式读取文件是否存在网络是否始终保持通畅等。

1.1 异常

再Java语言中,将程序执行过程中发生的不正常情况称为“异常”。(在开发过程中的语法错误和逻辑错误不是异常啊)

1.2.异常分类

1.2.1 Error

Java虚拟机无法解决的问题。如:JVM系统内部错误、资源耗尽等严重情况。
比如:StackOverflowError 和 OOM。一般不编写针对性的代码处理

1.2.2 exception

其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。比如:

空难指针访问;
试图读取不存在的文件;
网络连接中断;
数组角标越界

2.常见异常

在Java中,常见的异常包括运行时异常和非运行时异常。

2.1.运行时异常

运行时异常是指在程序运行过程中可能出现的异常,编译器不会强制要求处理这些异常。常见的运行时异常包括:

  • NullPointerException(空指针异常):当一个对象引用为null时,调用该对象的方法或访问其属性会抛出该异常。
  • ArrayIndexOutOfBoundsException(数组越界异常):当访问数组中不存在的索引时,会抛出该异常。
  • ArithmeticException(算术异常):当进行除法运算时,除数为0会抛出该异常。
  • ClassCastException(类转换异常):当试图将一个对象强制转换为不是其子类的类型时,会抛出该异常。

2.2.非运行时异常

非运行时异常是指在程序运行过程中可能出现的异常,编译器会强制要求处理这些异常。常见的非运行时异常包括:

  • IOException(输入输出异常):当发生输入输出错误时,会抛出该异常。
  • FileNotFoundException(文件未找到异常):当试图打开一个不存在的文件时,会抛出该异常。
  • ClassNotFoundException(类未找到异常):当试图加载不存在的类时,会抛出该异常。
  • SQLException(SQL异常):当操作数据库发生错误时,会抛出该异常。

这些是Java中常见的异常,根据具体的情况,我们可以使用try-catch语句来捕获并处理这些异常。

3.异常处理机制一:try-catch-finally

3.1.try

try:尝试

将有可能出现异常的代码 使用try包括起来

try不能单独出现,必须结合catch或者finally来使用

package com.yc.test1;

import java.util.InputMismatchException;
import java.util.Scanner;

/**
 * 	使用Java异常处理机制来处理异常
 * 	try:尝试
 * 		将有可能出现异常的代码 使用try包括起来
 * 		try不能单独出现,必须结合catch或者finally来使用
 * 	catch:捕获
 * 		表示出现异常并且捕获到该异常将会执行的代码块
 * 
 * 	处理异常情况1:
 * 	使用try-catch捕获到出现的异常
 */
public class Test2 {
	public static void main(String[] args) {
		try {
			Scanner in = new Scanner(System.in);
			System.out.print("请输入被除数:");
			int num1 = in.nextInt();
			System.out.print("请输入除数:");
			int num2 = in.nextInt();
			System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
		}catch(ArithmeticException e) {
			System.err.println("出现了输入不匹配异常");
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
		System.out.println("感谢使用本程序!");
	}
}

2.catch:捕获

表示出现异常并且捕获到该异常将会执行的代码块

处理异常情况2:
使用try-catch捕获多种异常
我们可以定义一个父类Exception来捕获到所有的异常,但是这样书写不利于代码阅读
我们推荐使用精确的异常类型来catch,书写多个catch 先子类 再父类

package com.yc.test1;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Test3 {
	public static void main(String[] args) {
		try {
			Scanner in = new Scanner(System.in);
			System.out.print("请输入被除数:");
			int num1 = in.nextInt();
			System.out.print("请输入除数:");
			int num2 = in.nextInt();
			System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
		}catch(ArithmeticException e) {
			System.err.println("出现了算数运算异常");
			e.printStackTrace();
		}catch(InputMismatchException e) {
			System.err.println("出现了输入不匹配异常");
			e.printStackTrace();
		}
		System.out.println("感谢使用本程序!");
	}
}

3.3.finally

finally :最终
用于表示不管是否出现异常,不管异常是否被捕获到,都将执行的代码

finally不能单独出现 必须结合try或者 try-catch

package com.yc.test2;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Test2 {
	public static void main(String[] args) {
		try {
			Scanner in = new Scanner(System.in);
			System.out.print("请输入被除数:");
			int num1 = in.nextInt();
			System.out.print("请输入除数:");
			int num2 = in.nextInt();
			System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
			System.exit(1); // 退出JVM虚拟机
		}catch(InputMismatchException e) {
			System.exit(0); // 退出JVM虚拟机
			e.printStackTrace();
		}finally {
			System.out.println("感谢使用本程序!");
		}
	}
}

3.4 finally面试题

  1. 不要在finally内 对返回值做操作
  2. 不要在finally内 return值
  3. finally中对返回值的操作 不会改变catch或者try中的return值
package com.yc.test3;

public class Test2 {
	public static void main(String[] args) {
		System.out.println(getNum());
	}
	public static int getNum() {
		int num = 10;
		try {
			num++;
			System.out.println(num / 0);
			return num; // 这里return值 num为11 表示返回值已经固定了
		} catch (Exception e) {
			num ++;
		}finally {
			num++;
		}
		return num;
	}
}

4. 手动抛出异常:throw

throw用于表示抛出异常,可以作为一条语句单独使用,抛异常之后不能再写代码,每一句只能抛出一个异常

package com.yc.test4;

import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;
/**
 * 	运行时异常和检查异常
 * 	RuntimeException和其子类 称之为运行时异常,方法声明了运行时异常,调用者不是必须处理;
 * 	除了RuntimeException和其子类 其他的都称之为检查异常。方法声明了检查异常,调用者必须处理。
 */
public class Test1 {
	public static void main(String[] args) {
		try {
			m1();
		} catch (InputMismatchException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ArithmeticException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			m2();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public static void m1() throws ArithmeticException,InputMismatchException {
		Scanner in = new Scanner(System.in);
		System.out.print("请输入被除数:");
		int num1 = in.nextInt();
		System.out.print("请输入除数:");
		int num2 = in.nextInt();
		System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
		System.out.println("欢迎使用程序");
	}
	
	
	/**
	 * 	CheckedException 检查异常
	 * @throws ClassNotFoundException
	 */
	public static void m2() throws ClassNotFoundException,FileNotFoundException {
		
    }
}

5.异常处理机制二:throws

throws表示声明异常,书写在形参列表之后,可以声明多个异常,多个异常使用逗号分隔,表示本方法有可能出现的异常

throws : 抛的复数形式。用于表示声明本方法可能会出现的异常 通知给调用者;
调用者可以:
1. 使用try-catch处理
2. 继续声明给JVM虚拟机

throw和throws

  • throw和throws的区别:
    throw用于表示抛出异常,可以作为一条语句单独使用,抛异常之后不能再写代码,每一句只能抛出一个异常;
    throws表示声明异常,书写在形参列表之后,可以声明多个异常,多个异常使用逗号分隔,表示本方法有可能出现的异常。
package com.yc.test4;
public class Test2 {
	public static void m1(int a) {
		if(a % 2 == 0) {
			System.out.println("条件成立");
		}else {
			throw new ArithmeticException("毫无意义的算数运算异常");
		}
	}
	
	public static void m2(int a) throws ClassNotFoundException {
		if(a % 2 == 0) {
			System.out.println("条件成立");
		}else {
			throw new ClassNotFoundException("毫无意义的类找不到异常");
		}
	}
}

6.用户自定义异常

JDK提供的异常有时候不能满足开发需求,我们可以自己定义异常。
我们可以自定义类继承Exception或者RuntimeException来实现异常定义

package com.yc.test5;

public class InputAgeException extends RuntimeException{

	private static final long serialVersionUID = 1L;

	public InputAgeException(String message) {
		super(message);
	}	
}
package com.yc.test5;

public class SetAgeException extends Exception{

	private static final long serialVersionUID = 1L; // 序列化ID
	
	public SetAgeException(String message) {
		super(message);
	}	
}
package com.yc.test5;

public class Student {
	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge1(int age) throws SetAgeException {
		if(age >= 0 && age <= 130) {
			this.age = age;
		}else {
			throw new SetAgeException("年龄必须在1~130之间");
		}
	}
	
	public void setAge2(int age) {
		if(age >= 0 && age <= 130) {
			this.age = age;
		}else {
			throw new InputAgeException("年龄必须在1~130之间");
		}
	}
	
	
	public static void main(String[] args) {
		Student stu1 = new Student();
		stu1.setName("赵四");
		try {
			stu1.setAge1(-112);
		} catch (SetAgeException e) {
			e.printStackTrace();
		}
		stu1.setAge2(-220);
	}
}
文章来源:https://blog.csdn.net/weixin_45754498/article/details/135466926
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。