前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大话Java异常

大话Java异常

原创
作者头像
ruochen
修改2021-05-17 10:20:46
6670
修改2021-05-17 10:20:46
举报

@toc

异常

异常的概述


  • 异常就是不正常的意思,Java语言中主要是指程序在运行阶段产生的错误
  • Throwable(可抛出的,可扔出的) - java.lang.Throwable 类是Java程序所有错误或异常的超类 - 主要有两个字类 - Error - Error主要描述比较严重的错误 - 无法通过编程来解决的重大的错误 - Exception - Exception主要m描述比较轻量级的错误 - 可以通过编程来解决

Exception类的主要分类

RuntimeException -> 运行时异常,也叫非检测性异常类


  • 非检测性异常类就是指b编译阶段无法被编译器检测出来的异常
  • 主要子类 - ArithmeticException -> 算数异常类 - ArrayIndexOutOfBoundsException(间接子类) -> 数组下标异常类 - NullPointerException -> 空指针异常 - ClassCastException -> 类型转换异常 - NumberFormatException(间接子类)-> 数字格式异常
  • 注意 - 当程序的执行过程中产生异常,若没有手动进行处理,则由Java虚拟机采用默认的方式进行处理,默认方式是打印异常名称、异常原因以及异常发生的位置并终止程序,后序代码无法被执行

IOException和其他异常类 -> 其他异常类,也叫做非检测性异常

案例

TestRuntimeException.java

代码语言:txt
复制
package demo1;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

/*
 * 		ArithmeticException -> 算数异常类
		ArrayIndexOutOfBoundsException(间接子类) -> 数组下标异常类
		NullPointerException -> 空指针异常
		ClassCastException -> 类型转换异常
		NumberFormatException(间接子类)-> 数字格式异常
 */

public class TestRuntimeException {
	public static void main(String[] args) {
		
		
		// 观察检测性异常
		// FileInputStream fis = new FileInputStream("c:/a.txt");
	
		// java.lang.ArithmeticException 算数异常
		int a = 10; 
		int b = 0;
		if (b != 0) {
			System.out.println(a/b);
		}

		// java.lang.ArrayIndexOutOfBoundsException 数组下标越界异常

		int[] arr = new int[3];
		int num = 3;
		if (num >= 0 && num < arr.length) {
			System.out.println(arr[num]);
		}
 

		// java.lang.NullPointerException

		String str = null; 
		if (str != null) {
			System.out.println(str.length());
		}

		// java.lang.ClassCastException

		Exception ex = new Exception(); 
		if (ex instanceof IOException) {
			IOException ie = (IOException) ex;
		}

		// java.lang.NumberFormatException

		String s = "12be"; 
		if (s.matches("\\d+")) {
			System.out.println(Integer.parseInt(s));
		}
		System.out.println("运行程序结束");

	}
}

异常处理

运行时异常的处理方式


  • 对于绝大数运行时异常来说,都可以通过条件判断避免异常的发生

异常的捕获


  • 语法格式 try{ 可能产生异常对象的语句块 }catch(异常类型 引用名){ 针对当前异常类型对象的处理语句块 } .... (可以写多个catch) finally{ 无论是否发生异常,都应该执行的语句块 }
  • 注意事项 - 当捕获的结构中有多个catch分支时,切记小范围的异常类型放在大范围的异常类型上面 - 懒人写法: catch(Exception e) {....}
  • 执行流程
代码语言:txt
复制
	try {
代码语言:txt
复制
		a;
代码语言:txt
复制
		b;  // 可能产生异常的语句
代码语言:txt
复制
		c;
代码语言:txt
复制
	} catch (Exception e) {
代码语言:txt
复制
		e;
代码语言:txt
复制
	} finally {
代码语言:txt
复制
		f;
代码语言:txt
复制
	}
代码语言:txt
复制
- 当没有产生异常的时候,程序的执行流程是:a b c f 
- 当产生异常时,程序的执行流程是: a b e f 
  • 案例 - TestExceptionCatch.java ```java package demo2; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException;
代码语言:txt
复制
public class TestExceptionCatch {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		// 声明引用指向本类的对象,用于读取文件中的内容
代码语言:txt
复制
		FileInputStream fis = null;
代码语言:txt
复制
		try {
代码语言:txt
复制
			// 随时可能产生文件找不到y异常对象, new FileNotFoundException()
代码语言:txt
复制
			fis = new FileInputStream("d:/a.txt");
代码语言:txt
复制
		} catch (FileNotFoundException e) {
代码语言:txt
复制
			// 打印异常的名称、异常原因、异常的位置等信息
代码语言:txt
复制
			e.printStackTrace();
代码语言:txt
复制
		}
代码语言:txt
复制
		try {
代码语言:txt
复制
			fis.close();
代码语言:txt
复制
		} catch (IOException e) {
代码语言:txt
复制
			e.printStackTrace();
代码语言:txt
复制
		} catch (NullPointerException e) {
代码语言:txt
复制
			// System.out.println("输出");
代码语言:txt
复制
			e.printStackTrace();
代码语言:txt
复制
		}
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestFinally.java
```java
package demo3;
代码语言:txt
复制
public class TestFinally {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		int a = 10;
代码语言:txt
复制
		int b = 0;
代码语言:txt
复制
		try {
代码语言:txt
复制
			System.out.println(a/b);
代码语言:txt
复制
		} catch (Exception e) {
代码语言:txt
复制
			e.printStackTrace();
代码语言:txt
复制
			return ;
代码语言:txt
复制
		} finally {
代码语言:txt
复制
			System.out.println("无论是否发生异常都会执行");
代码语言:txt
复制
		}
代码语言:txt
复制
		System.out.println("程序结束");
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	java.lang.ArithmeticException: / by zero
代码语言:txt
复制
	无论是否发生异常都会执行
代码语言:txt
复制
	at demo3.TestFinally.main(TestFinally.java:9)

异常的抛出

  • 基本概念 - 某些特殊的场合中,当产生异常后却无法直接处理/不想处理时,此时就可以将异常转移给当前方法的调用者,这就叫异常的抛出
  • 语法格式 - 返回值类型 方法名称(形参列表) throws 异常类型{....}
  • 方法重写的原则 - 要求方法名相同、参数列表相同、返回值类型也相同,从jdk1.5开始允许返回子类类型 - 范围权限不能变小,可以相同或者变大 - 不能抛出更大的异常 - 注意 - 子类中重写以后的方法可以选择抛出与父类一样的异常、更小的异常、不抛出异常,但是不能抛出更大的异常、不同的异常 - 案例 A.java ```java package demo4;
代码语言:txt
复制
		import java.io.IOException;
代码语言:txt
复制
		public class A {
代码语言:txt
复制
			public void show() throws IOException{
代码语言:txt
复制
				System.out.println("A");
代码语言:txt
复制
			}
代码语言:txt
复制
		}
代码语言:txt
复制
		```
代码语言:txt
复制
		SubA.java
代码语言:txt
复制
		```java
代码语言:txt
复制
		package demo4;
代码语言:txt
复制
		import java.io.IOException;
代码语言:txt
复制
		import java.io.FileNotFoundException;
代码语言:txt
复制
		import javax.print.PrintException;
代码语言:txt
复制
		public class SubA extends A{
代码语言:txt
复制
			@Override
代码语言:txt
复制
			// public void show() throws IOException {
代码语言:txt
复制
			// public void show() throws FileNotFoundException {
代码语言:txt
复制
			// public void show() throws PrintException {
代码语言:txt
复制
			// public void show() throws Exception {
代码语言:txt
复制
			public void show() {
代码语言:txt
复制
			}
代码语言:txt
复制
		}
代码语言:txt
复制
		```
代码语言:txt
复制
	>显然不能抛出更大的异常

自定义异常

  • 自定义异常的由来 - Java官方库中虽然提供了大量的异常类,但不足以描述现实生活中所有的异常情况。当出现官方库中没有m描述的异常情况,这个时候就需要程序员自定义异常类加以描述,使得异常信息更加具备针对性和可读性
  • 自定义异常的流程 - 自定义类继承自Exception类或者Exception类的子类 - 提供两个版本的构造方法,一个是无参构造方法,另一个是字符串做参数的构造方法
  • 自定义异常 -- >案例1 - Person.java ```java package demo5;
代码语言:txt
复制
public class Person {
代码语言:txt
复制
	private String name;
代码语言:txt
复制
	private int age;
代码语言:txt
复制
	public Person() {
代码语言:txt
复制
		super();
代码语言:txt
复制
	}
代码语言:txt
复制
	public Person(String name, int age) throws Exception {
代码语言:txt
复制
		super();
代码语言:txt
复制
		setName(name);
代码语言:txt
复制
		setAge(age);
代码语言:txt
复制
	}
代码语言:txt
复制
	public String getName() {
代码语言:txt
复制
		return name;
代码语言:txt
复制
	}
代码语言:txt
复制
	public void setName(String name) {
代码语言:txt
复制
		this.name = name;
代码语言:txt
复制
	}
代码语言:txt
复制
	public int getAge() {
代码语言:txt
复制
		return age;
代码语言:txt
复制
	}
代码语言:txt
复制
	public void setAge(int age) throws Exception {
代码语言:txt
复制
		if(age > 0 && age < 150) {
代码语言:txt
复制
			this.age = age;
代码语言:txt
复制
		} else {
代码语言:txt
复制
			// System.out.println("年龄不合理");
代码语言:txt
复制
			// 手动产生一个异常对象并抛出
代码语言:txt
复制
			// throw new Exception();
代码语言:txt
复制
			throw new AgeException("年龄不合理!");
代码语言:txt
复制
		}
代码语言:txt
复制
		System.out.println("产生异常的效果");
代码语言:txt
复制
	}
代码语言:txt
复制
	@Override
代码语言:txt
复制
	public String toString() {
代码语言:txt
复制
		return "Person [name=" + name + ", age=" + age + "]";
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- AgeException.java
```java
package demo5;
代码语言:txt
复制
public class AgeException extends Exception {
代码语言:txt
复制
	/**
代码语言:txt
复制
	 * 
	 */
	private static final long serialVersionUID = 1L;
代码语言:txt
复制
	// 自定义无参的构造方法
代码语言:txt
复制
	public AgeException() {
代码语言:txt
复制
	}
代码语言:txt
复制
	// 自定义使用字符串作为参数的构造方法
代码语言:txt
复制
	public AgeException(String msg) {
代码语言:txt
复制
		super(msg);
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestPerson.java
```java
package demo5;
代码语言:txt
复制
public class TestPerson {
代码语言:txt
复制
	public static void main(String[] args) {
代码语言:txt
复制
		Person p = null;
代码语言:txt
复制
		try {
代码语言:txt
复制
			p = new Person("张三", -12);
代码语言:txt
复制
		} catch (Exception e) {
代码语言:txt
复制
			// TODO Auto-generated catch block
代码语言:txt
复制
			e.printStackTrace();
代码语言:txt
复制
		}
代码语言:txt
复制
		System.out.println(p);
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	demo5.AgeException: 年龄不合理!
代码语言:txt
复制
	null
代码语言:txt
复制
	at demo5.Person.setAge(Person.java:33)
代码语言:txt
复制
	at demo5.Person.<init>(Person.java:15)
代码语言:txt
复制
	at demo5.TestPerson.main(TestPerson.java:8)
  • 自定义异常 -- > 案例2 - Student.java ```java package demo6;
代码语言:txt
复制
public class Student {
代码语言:txt
复制
	private String name;
代码语言:txt
复制
	private int id;
代码语言:txt
复制
	public Student() {
代码语言:txt
复制
		super();
代码语言:txt
复制
	}
代码语言:txt
复制
	public Student(String name, int id) throws IDException {
代码语言:txt
复制
		super();
代码语言:txt
复制
		setName(name);
代码语言:txt
复制
		setId(id);
代码语言:txt
复制
	}
代码语言:txt
复制
	public String getName() {
代码语言:txt
复制
		return name;
代码语言:txt
复制
	}
代码语言:txt
复制
	public void setName(String name) {
代码语言:txt
复制
		this.name = name;
代码语言:txt
复制
	}
代码语言:txt
复制
	public int getId() {
代码语言:txt
复制
		return id;
代码语言:txt
复制
	}
代码语言:txt
复制
	public void setId(int id) throws IDException {
代码语言:txt
复制
		if (id > 0) {
代码语言:txt
复制
			this.id = id;
代码语言:txt
复制
		} else {
代码语言:txt
复制
			// System.out.println("学号不合理");
代码语言:txt
复制
			throw new IDException("学号不合理");
代码语言:txt
复制
		}
代码语言:txt
复制
		System.out.println("结束");
代码语言:txt
复制
	}
代码语言:txt
复制
	@Override
代码语言:txt
复制
	public String toString() {
代码语言:txt
复制
		return "Student [name=" + name + ", id=" + id + "]";
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- IDException.java
```java
package demo6;
代码语言:txt
复制
public class IDException extends Exception {
代码语言:txt
复制
	/**
代码语言:txt
复制
	 * 
	 */
	private static final long serialVersionUID = 1L;
代码语言:txt
复制
	public IDException() {
代码语言:txt
复制
	}
代码语言:txt
复制
	public IDException(String msg) {
代码语言:txt
复制
		super(msg);
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
- TestStudent.java
```java
package demo6;
代码语言:txt
复制
public class TestStudent {
代码语言:txt
复制
	public static void main(String[] args) throws IDException {
代码语言:txt
复制
		/*Student stu = null;
代码语言:txt
复制
		try {
代码语言:txt
复制
			stu = new Student("小王", -5);
代码语言:txt
复制
		} catch (IDException e) {
代码语言:txt
复制
			// TODO Auto-generated catch block
代码语言:txt
复制
			e.printStackTrace();
代码语言:txt
复制
		}*/ 
代码语言:txt
复制
		Student stu = new Student("小王", -5);
代码语言:txt
复制
		System.out.println(stu);
代码语言:txt
复制
	}
代码语言:txt
复制
}
代码语言:txt
复制
```
代码语言:txt
复制
	Exception in thread "main" demo6.IDException: 学号不合理
代码语言:txt
复制
	at demo6.Student.setId(Student.java:30)
代码语言:txt
复制
	at demo6.Student.<init>(Student.java:14)
代码语言:txt
复制
	at demo6.TestStudent.main(TestStudent.java:14)

此处有一点要注意,在案例一的TestPerson中,在main函数中,我们使用try....catch语句,异常由内部进行处理,会打印后面的语句

而在案例二的TestStudent中,我们将异常直接交给main函数处理,也就是交给虚拟机处理,所以并不会执行后面的语句

异常对象的抛出

  • throw new 异常类型()
  • 例如: - throw new Exception()

最后简单介绍一下throws和throw的区别

throws和throw的区别

  • throws - 用在方法声明后面,跟的是异常类名 - 可以跟多个异常类名,用逗号隔开 - 表示抛出异常,由该方法的调用者来处理 - throws表示出现异常的一种可能性,并不一定会发生这些异常
  • throw - 用在方法体内,跟的异常对象名 - 只能抛出一个异常对象名 - 表示抛出异常,由方法体内的语句实现 - throw则是抛出了异常,执行throw则一定抛出了某种异常

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 异常
    • 异常的概述
      • Exception类的主要分类
        • RuntimeException -> 运行时异常,也叫非检测性异常类
        • IOException和其他异常类 -> 其他异常类,也叫做非检测性异常
        • 案例
      • 异常处理
        • 运行时异常的处理方式
        • 异常的捕获
        • 异常的抛出
        • 自定义异常
        • 异常对象的抛出
        • throws和throw的区别
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档