异常( Exception)
定义:
异常代表程序出现的问题
图来自黑马程序员
分类:
- 运行时异常:RuntimeException以及其子类,编译阶段不会出现异常提醒,运行时出现的异常(如数组越界异常)
- 编译时异常:编译阶段就会出现异常提醒的(如日志解析异常),直接继承于Exception
图来自黑马程序员网课
作用:
- 用来查询bug的关键参考信息
- 可以作为方法内部的一种特殊返回值,以便通知调用者底层的执行情况
异常处理方式:
1.JVM默认的处理方式
把异常的名称,异常原因及异常出现的位置等信息输出在控制台
程序停止执行,下面的代码不会执行
package com.lazyGirl.exceptiondemo;
public class Demo1 {
public static void main(String[] args) {
System.out.println("hhhhhhhhhhhhhhhhhhh");
System.out.println(2 / 0);
System.out.println("gggg");
}
}
输出:
2. 捕获异常
图来自黑马程序员
package com.lazyGirl.exceptiondemo;
public class Demo2 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
try {
System.out.println(arr[5]);
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界");;
}
System.out.println("看看我执行了吗");
}
}
输出:
若try语句出现异常,程序就会在这里创建一个异常对象,拿着这个对象到catch小括号中对比,看括号中的变量是否可以接受这个对象,如果能被接受,就表示该异常能被捕获,执行catch里对应的代码,当try。。catch执行完毕,接着执行下面其他代码
问题一:如果try中没有遇到问题,怎么执行?
会把try里面的代码全部执行完毕,不会执行catch里面的代码,因此,当出现异常才会执行catch里面的语句
package com.lazyGirl.exceptiondemo;
public class Demo3 {
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("看看我执行了吗");
}
}
输出:
问题二:如果try中遇到多个问题,怎么执行?
会写多个catch与之对应,若捕获多个异常,这些异常中如果存在父子关系的话,那么父类一定要写在下面
package com.lazyGirl.exceptiondemo;
public class Demo3 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
try {
System.out.println(arr[5]);
System.out.println(2 / 3);
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("索引越界");;
}catch (ArithmeticException e) {
System.out.println("除0异常");
}
System.out.println("看看我执行了吗");
}
}
输出:
问题三: 若try中遇到的问题没有被捕获,怎么执行?
JVM默认处理异常方式
问题四: 若try中遇到的问题没有被捕获,怎么执行?
若try中遇到了异常,直接跳转到对应的catch当中,执行catch里面的语句体,若没有与之匹配的catch,则会交给虚拟机处理
Throwable的成员方法:
图来自黑马程序员网课
package com.lazyGirl.exceptiondemo;
public class Demo4 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
try {
System.out.println(arr[5]);
}catch (ArrayIndexOutOfBoundsException e){
String message = e.getMessage();
System.out.println(message);
String str = e.toString();
System.out.println(str);
e.printStackTrace();
}
System.out.println("看看我执行了吗");
}
}
printStackTrace()在底层是利用System.err.println进行输出,把异常的错误信息以红色字体输出在控制台 ,仅打印信息,不会停止程序运行
输出:
3. 抛出异常
throws 与throw
图来自黑马程序员
throw:
package com.lazyGirl.exceptiondemo;
public class Demo5 {
public static void main(String[] args) {
int[] a = null;
System.out.println(getMax(a));
}
public static int getMax(int[] arr) {
if(arr == null || arr.length == 0){
throw new NullPointerException();
}
System.out.println("看看我执行了吗");
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
}
输出:
throws:
public static int getMax(int[] arr) throws NullPointerException ,ArrayIndexOutOfBoundsException{
if(arr == null || arr.length == 0){
throw new NullPointerException();
}
System.out.println("看看我执行了吗");
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
自定义异常
步骤:
- 定义异常类
- 写继承关系
- 空参构造
- 带参构造
package com.lazyGirl.exceptiondemo;
public class NameFormatException extends RuntimeException {
public NameFormatException() {}
public NameFormatException(String message) {
super(message);
}
}
package com.lazyGirl.exceptiondemo;
public class BoyFriend {
private String name;
private int age;
public BoyFriend() {
}
public BoyFriend(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
int len = name.length();
if (len < 3 || len > 10){
throw new NameFormatException(name + "格式长度有误");
}
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) {
throw new AgeOutOfBoundsException(age + "年龄有误");
}
this.age = age;
}
@Override
public String toString() {
return "BoyFriend{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.lazyGirl.exceptiondemo;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
BoyFriend bf = new BoyFriend();
Scanner sc = new Scanner(System.in);
while (true){
try {
System.out.println("男朋友的名字");
String name = sc.nextLine();
bf.setName(name);
System.out.println("男朋友年龄");
String ageStr= sc.nextLine();
bf.setAge(Integer.parseInt(ageStr));
break;
}catch (NameFormatException e){
e.printStackTrace();
}catch (AgeOutOfBoundsException e){
e.printStackTrace();
}
}
System.out.println(bf);
}
}
输出: