在Java中我们把程序执行过程中不正常的行为称为异常。
一 常见的异常
1.算数异常
public class Test {
public static void main(String[] args) {
int a=10;
System.out.println(a/0);
}
}
2.数组越界异常
public class Test {
public static void main(String[] args) {
char[] array={1,2,3};
System.out.println(array[5]);
}
3.空指针异常
public class Test {
public static void main(String[] args) {
char[] array=null;
System.out.println(array.length);
}
二 异常的体系结构
1.throwable是异常类的顶层类,是所有异常类的父类 ,Error 和 Exception
2.Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表: StackOverflowError和OutOfMemoryError,一旦发生回力乏术。
3.Exception:指的是程序员可以通过修改代码处理的异常。
三 异常的分类
1.编译时异常
一般发生在编译期间,也称为受检查异常(Checked Exception)
public class Test {
public static void main(String[] args) {
Person person=new Person();
Person person1=(Person)person.clone();
}
2.运行时异常
在运行之后才会显示的异常
四 异常的处理
在Java中,异常时根据一些关键词来处理的,try,catch,finally,throw,throws。这些关键词提供了结构化的方法来处理运行时的异常。
1.try-catch结构
try
关键字用于包含可能会抛出异常的代码块,catch
用于捕获和处理异常。
基本结构
try {
// 可能会抛出异常的代码
} catch (ExceptionType1 e1) {
// 处理 ExceptionType1 异常
} catch (ExceptionType2 e2) {
// 处理 ExceptionType2 异常
} finally {
// 无论是否抛出异常,finally 代码块都会执行
}
示例:
public class Test {
public static void function(int a)throws CloneNotSupportedException{
if(a==10){
throw new CloneNotSupportedException();
}
}
public static void main(String[] args) {
try {
function(10);
System.out.println("符合了异常条件");
}catch(CloneNotSupportedException e){
System.out.println("捕获了异常,处理异常");
}finally {
System.out.println("lalalalala");
}
System.out.println("没有问题,程序正常运行");
}
注:如果有异常,则抛出异常的代码块,异常后面的代码无法运行。
finally 代码块无论何时都会执行。
2.多重捕获
如果代码匹配哪个异常,则会进行哪个catch块进行处理
public static void main(String[] args) {
try {
int[] arr=new int[3];
arr[5]=8;
}catch (ArithmeticException e){
System.out.println("算数异常"+e.getMessage());
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("数组越界异常"+e.getMessage());
}finally {
System.out.println("结束");
}
}
如果没有匹配到合适的catch,代码则会继续向上执行,直到合适的地方捕获到异常,或者直接崩溃。
注:
在Java 7之后允许一个代码块执行多个异常
public static void main(String[] args){
try {
int[] arr = new int[3];
arr[5] = 8;
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("算数异常" + e.getMessage() + "数组越界异常" + e.getMessage());
} finally {
System.out.println("结束");
}
}
3.finally块
finally块的代码无论是否抛出异常,都会被执行,通常用于清理资源,如关闭文件、释放数据库连接等。如果try-catch中有return,代码块也会被执行。
public static void main(String[] args) {
try {
int[] arr=new int[3];
arr[5]=8;
}catch (ArithmeticException e){
System.out.println("算数异常"+e.getMessage());
return;
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("数组越界异常"+e.getMessage());
return;
}finally {
System.out.println("结束");
}
}
4. throw
throw关键词用于手动抛出异常,可以被用于任何地方
public static void sex(String sex){
if(sex=="男"){
throw new ArithmeticException("不能进入女子队");
}else {
System.out.println("可以进入女子队伍");
}
}
public static void main(String[] args) {
sex("男");
}
满足性别为男性时,程序手动抛出 ArithmeticException
。
5.throws
throws关键词用于声明,表示该方法可能抛出的哪些异常,被标记的异常要么被捕捉,要么在方法调用的地方继续抛出。
public static void ReadFile() throws IOException {
FileReader fileReader=new FileReader("text.c");
}
public static void main(String[] args) throws IOException{
ReadFile();
}
6.自定义异常
Java 允许你定义自己的异常类,通常通过继承 Exception
或 RuntimeException
来实现。自定义异常可以帮助你根据业务逻辑定义特殊的错误情况。
如果不用自定义异常的方法写一个登录途径
class login{
private String name;
private String num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public static void login(String name,String num ){
Scanner scanner=new Scanner(System.in);
if(!name.equals(name)){
System.out.println("姓名输入错误");
return;
}else if (!num.equals(num)){
System.out.println("账号输入错误");
return;
}
System.out.println("登陆成功");
}
public static void main(String[] args) {
login("zhangsan","123456");
}
}
使用自定义异常
class NameException extends Exception {
public NameException(String message) {
super(message);
}
}
class NumException extends Exception {
public NumException(String message) {
super(message);
}
}
class login{
private String name;
private String num;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
public static void login(String name,String num ) throws NameException,NumException{
Scanner scanner=new Scanner(System.in);
if(!name.equals(name)) {
throw new NameException("姓名输入错误");
}else if (!num.equals(num)){
throw new NumException("账号输入错误");
}
System.out.println("登陆成功");
}
public static void main(String[] args) {
try {
login("zhangsan","123456");
}catch (NameException e){
e.printStackTrace();
}catch (NumException e){
e.printStackTrace();
}
}
}
7. 总结:
- try-catch-finally 是异常处理的核心结构,
try
用于包含可能抛出异常的代码,catch
用于捕获和处理异常,finally
块用于清理资源。 throw
用于手动抛出异常,而throws
用于声明方法可能抛出的异常。- 处理异常时,建议只捕获你能处理的异常,避免捕获过于笼统的异常,如直接捕获
Exception
,这样会掩盖潜在的编程错误。 finally
块应尽可能用于释放资源,避免资源泄露问题。- 通过自定义异常,可以根据业务需求定义特定的异常来增强代码的可读性和可维护性。
希望能对大家有所帮助!!!!!!!