JAVA进阶 —— 异常

目录

一、 异常介绍

 二、 异常体系介绍

三、异常作用

四、异常处理方式

1. JVM默认的处理方式

2. 捕获异常

2.1 灵魂一问: 如果try中没有遇到问题,如何执行?

2.2 灵魂二问:如果try中可能会遇到多个问题,怎么执行?

2.3 灵魂三问:如果try中遇到的问题没有被捕获,怎么执行?

2.4 灵魂四问:如果try中遇到了问题,那么try下面的其他代码还会执行吗?

3. 抛出异常

 五、 异常中常见方法


一、 异常介绍

异常: 异常就是代表程序出现的问题。

误区: 此时不是让我们以后不出现异常,而是程序出现了异常以后,该如何处理。

例如:你觉得以下代码有异常吗?

 二、 异常体系介绍

 Error:代表的系统级别错误(属于严重错误)

系统一旦出现问题,sun公司会把这些错误封装成Error对象。

Error是给sun公司自己用的,不是给我们程序员用的。

因此我们开发人员不用管它


Exception:叫做异常,代表程序可能出现的问题

                     我们通常会用Exception以及他的子类来封装程序出现的问题。

运行时异常:RuntimeException及其子类编译阶段不会出现异常提醒。

                     运行时出现的异常。(如:数组索引越界异常)

编译时异常:没有继承RuntimeException的异常,直接继承与Exception。

                      编译阶段就会出现异常提醒。(如:日期解析异常)

public class ExceptionDemo01 {
	public static void main(String[] args) throws ParseException {
		// 编译时异常(在编译阶段,必须手动处理,否则代码报错)
		String time = "2030年1月1日";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
		// parse报错 手动处理添加 throws ParseException
		Date data = sdf.parse(time);
		System.out.println(data);

		// 运行时异常(在编译阶段不需要处理,是代码运行时出现的异常)
		int[] arr = { 1, 2, 3, 4, 5 };
		// 数组越界异常
		System.out.println(arr[10]); // ArrayIndexOutOfBoundsException

	}
}

 因此,我们需要注意编译时异常和运行时异常的区别:

编译时异常

除了RuntimeException和其子类,其他都是编译时异常。

编译阶段需要进行处理,作用在于提醒程序员。

运行时异常

RuntimeException本身和所有的子类,都是运行时异常。

编译阶段不报错,是程序运行时出现的。

一般是由于参数传递错误带来的问题。

三、异常作用

  • 作用一:异常时用来查询bug的关键参考信息
  • 作用二:异常可以作为方法内部的一种特殊返回值,以便通知调试者底层的执行情况。
//作用一
public class ExceptionDemo02 {
	public static void main(String[] args) {
		Student[] arr = new Student[3];
		String name = arr[0].getName();
		//arr[0] is null
		System.out.println(name); //NullPointerException
	}
}

//作用二
public class ExceptionDemo03 {
	public static void main(String[] args) {
		// 1.创建学生对象
		Student s1 = new Student();
		// 年龄:18~40岁
		s1.setAge(50); // 50赋值失败 : RuntimeException
		// 选择1:自己处理
		// 选择二:打印在控制台上

	}
}


//Student.java
public class Student {
	private String name;
	private int age;

	public Student() {
	}

	public Student(String str) {
		String[] arr = str.split("-");
		this.name = arr[0];
		this.age = Integer.parseInt(arr[1]);
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		// 这样筛选年龄
		// 只能将结果直接打印在控制台上
		// 开发人员无法直接查看
		if (age < 18 || age > 40) {
			// System.out.println("年龄超出范围");
			throw new RuntimeException();
		} else {
			this.age = age;
		}
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
}

四、异常处理方式

  1. JVM默认的处理方式:把异常信息以红色字体打印在控制台,并结束程序
  2. 捕获异常 try...catch:一般用在调用处,能让代码继续往下运行。
  3. 抛出异常 throw、throws:
  • 在方法中,出现异常了。
  • 方法就没有继续运行下去的意义了,采取抛出处理。
  • 让该方法结束运行并告诉调用者出现了问题。

1. JVM默认的处理方式

  • 把异常的名称,异常原因及异常出现的位置等信息输出在了控制台
  • 程序停止执行,下面的代码不会再执行了
public class ExceptionDemo04 {
	public static void main(String[] args) {
		System.out.println("aaa");
		System.out.println(2 / 0); // 算术异常 ArithmeticException: / by zero
		// 以下两行输出语句不能执行
		System.out.println("bbb");
		System.out.println("ccc");
	}
}

2. 捕获异常

格式:

try{
    可能出现异常的代码;
}catch(异常类名  变量名){
     异常的处理代码;
}

目的:当代码出现异常时,可以让程序继续往下执行。

public class ExceptionDemo05 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 };
		// System.out.println(arr[10]); //ArrayIndexOutOfBoundsException: 10
		// System.out.println("看看我执行了吗"); //没有执行

		try {
			// 可能出现异常代码
			System.out.println(arr[10]);
			//此处出现异常,程序就会在这里创建一个ArrayIndexOutOfBoundsException对象
			// new ArrayIndexOutOfBoundsException();
			//拿着对象到catch的小括号中进行对比,看括号内变量是否可以接收这个对象
			//如果能被接受,表示该异常可以被捕获,执行catch里面对应代码
			//当catch里面所有代码执行完毕,继续执行try...catch体系外其他代码
		} catch (ArrayIndexOutOfBoundsException e) {
			// 如果出现异常 我们该如何处理
			System.out.println("索引越界");
		}
		System.out.println("看看我执行了吗");
		// 索引越界
		// 看看我执行了吗
	}
}

2.1 灵魂一问: 如果try中没有遇到问题,如何执行?

  • 会把try里面的所有的代码执行完毕,不会执行catch里面的代码。

注意:只有当出现了异常,才会执行catch里面的代码

public class ExceptionDemo06 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 };

		try {
			System.out.println(arr[0]);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("索引越界");
		}
		System.out.println("看看我执行了吗");
		// 1
		// 看看我执行了吗
	}
}

2.2 灵魂二问:如果try中可能会遇到多个问题,怎么执行?

  • 会写多个catch与之对应。

细节:如果我们要捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面

了解性:在JDK7之后,我们可以在catch中同时捕获多个异常,中间用 | 进行隔开。

public class ExceptionDemo07 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 };

		try {
			System.out.println(arr[10]); // ArrayIndexOutOfBoundsException
			System.out.println(2 / 0); // ArithmeticException
			String s = null;
			System.out.println(s.equals("abc"));
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("索引越界");
		} catch (ArithmeticException e) {
			System.out.println("除数不能为0");
		} catch (NullPointerException e) {
			System.out.println("空指针异常");
		} catch (Exception e) {
			//父类异常
			System.out.println("exception");
		}
		System.out.println("看看我执行了吗");
		// 索引越界
		// 看看我执行了吗
	}
}

2.3 灵魂三问:如果try中遇到的问题没有被捕获,怎么执行?

  • 相当于try...catch代码没有执行,最终还是会交给虚拟机进行处理。
public class ExceptionDemo08 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 ,6};

		try {
			System.out.println(arr[10]); //ArrayIndexOutOfBoundsException
			// new ArrayIndexOutOfBoundsException();
		} catch (NullPointerException e) {
			System.out.println("空指针异常");
		}
		System.out.println("看看我执行了吗");
	}
}

2.4 灵魂四问:如果try中遇到了问题,那么try下面的其他代码还会执行吗?

  • 不会执行,直接跳转到对应的catch当中,执行catch里面的语句体。
  • 但是如果没有对应的语句体,那么还是会交给虚拟机进行处理。
public class ExceptionDemo09 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 ,6};

		try {
			System.out.println(arr[10]); 
			System.out.println("看看我执行了吗...try");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("索引越界");
		}
		System.out.println("看看我执行了吗...其他代码");
		//索引越界
		//看看我执行了吗...其他代码
	}
}

3. 抛出异常

throwsthrow

注意:写在方法定义处,表示声明一个异常

           告诉调用者,使用本方法可能会有哪些异常

注意:写在方法内,结束语句

          手动抛出异常对象,交给调用者

          方法中下面的代码不再执行

  • 编译时异常:必须要写
  • 运行时异常:可以不写
public class ExceptionDemo10 {
	public static void main(String[] args) {
		// 需求:定义一个方法求数组最大值

		// int[] arr = { 1, 2, 3, 4, 5 };
		// 以下两种数组代码无法运行
		int[] arr = null;
		int max = 0;
		// int[] arr = {};
		// 进行捕获
		try {
			max = getMax(arr);
		} catch (NullPointerException e) {
			System.out.println("空指针异常");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("索引越界异常");
		}
		System.out.println(max);
	}

	// public static int getMax(int[] arr) throws
	// NullPointerException,ArrayIndexOutOfBoundsException{
	// 都属于RuntimeException 运行时异常 可以不写
	public static int getMax(int[] arr) {
		if (arr == null) {
			// 手动创建一个异常对象 并把这个异常交给方法的调用者处理
			// 此时方法结束,下面代码不再执行
			throw new NullPointerException();
		}

		if (arr.length == 0) {
			throw new ArrayIndexOutOfBoundsException();
		}
		System.out.println("看看我执行了吗");
		int max = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		return max;
	}
}

 五、 异常中常见方法

Throwable的成员方法:

方法名称说明
public String getMessage ( )返回此throwable的详细消息字符串
public String toString ( )返回此可抛出的简短描述
public void printstackTrace ( )把异常的错误信息输出在控制台
public class ExceptionDemo11 {
	public static void main(String[] args) {
		int[] arr = { 1, 2, 3, 4, 5 };

		try {
			System.out.println(arr[10]);
		} catch (ArrayIndexOutOfBoundsException e) {
			String message = e.getMessage();
			System.out.println(message); // Index 10 out of bounds for length 6

			String str = e.toString();
			System.out.println(str); // java.lang.ArrayIndexOutOfBoundsException:10

			e.printStackTrace(); // at Exception.ExceptionDemo11.main(ExceptionDemo11.java:8)
			// 仅仅打印信息,不会停止程序运行
		}

		System.out.println("看看我执行了吗");
	}
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hgngy.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值