java学习笔记-异常
1.概述
异常:程序出现了不正常的情况
注意:语法错误不算在异常体系中
异常体系:
Throwable:
- Error (严重问题 通过代码无法进行处理,比如内存溢出)
- Exception->分为 RountineException以及他的子类 和 RoutineException之外所有的异常
Exception: 称为异常类 他表示程序本身可以处理的问题
RountineException及其子类:运行异常 空指针异常,数组索引越界异常
RoutineException之外所有的异常: 编译异常 编译期间必须处理的 否则程序不能通过编译
编译异常:将java文件编译成.class字节码文件时,必须要处理的异常,也称之为受检异常
运行异常:运行字节码文件时出现的异常
如果程序出现了问题:JVM做出默认的处理
- 把异常的名称 异常的原因 以及异常出现的位置 等信息输出在控制台
- 程序停止运行
2.异常处理方式
- Throws: throws 异常类名 告诉调用者 可能出现这样的异常 如果方法中没有出现该异常 那么正常执行,如果方法中真的出现了这个异常,那么将这个异常交给了调用者处理(如果调用者也没有处理 那么交给虚拟机处理)
//如果声明的异常是一个运行时异常 那么声明的代码可以不写
//如果声明的异常是一个编译时异常 声明的代码必须写
package com.ustc.test10;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class 异常 {
public static void main(String[] args) throws ParseException {
method1();
method2();
}
//如果声明的异常时编译时异常 必须在方法名后面显示声明
private static void method2() throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
sdf.parse("2048年10月10日");
}
//如果声明的异常是一个运行时异常 那么声明的代码可以不写
private static void method1() throws NullPointerException{
int[] arr = null;
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
- 格式:throw new 异常();//创建一个异常对象 该异常对象创建之后,暂时没有手动处理 抛给调用者处理 下面的代码不会执行
对比:
Throws: 用在方法声明之后 跟的是异常类名
表示声明异常 调用该方法有可能出现这样的异常
Throw: 用在方法体内部 跟的是异常对象名
表示手动抛出异常对象 由方法体内部的语句处理
抛出处理异常的意义:
1. 当传递的参数有问题 没有继续下去的必要 则采取抛出处理 表示让该方法结束运行
2. 告诉调用者方法中出现了问题
package com.ustc.test10;
public class test2 {
public static void main(String[] args) {
// int[] arr = {1,2,3,4,5,6};
int[] arr = null;
printarr(arr); //就会接收到 采取虚拟机默认处理方式
}
private static void printarr(int[] arr) {
if(arr == null)
{
//当参数为Null 手动创建一个异常对象 抛给了调用者
throw new NullPointerException();
}
else
{
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
}
- try-catch
package com.ustc.test10;
public class test2 {
public static void main(String[] args) {
// int[] arr = {1,2,3,4,5,6};
int[] arr = null;
try{
//可能出现异常的代码
printarr(arr); //就会接收到 采取虚拟机默认处理方式
}catch(NullPointerException e){
//如果出现了这样的异常 进行下面的操作
System.out.println("参数不可以为null");
}
}
private static void printarr(int[] arr) {
if(arr == null)
{
//当参数为Null 手动创建一个异常对象 抛给了调用者
throw new NullPointerException();
}
else
{
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
}
-
Question:
- 如果try中没有遇到问题 怎么执行 :不会执行catch
package com.ustc.test10;
import java.util.Scanner;
public class test3 {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的年龄:");
String age = sc.nextLine();
int age1 = Integer.parseInt(age); //int包装类 直接调用静态方法 parseInt 解析字符串为Int
System.out.println(age1);
System.out.println("测试1"); //执行了
} catch (NumberFormatException e) {
System.out.println("执行吗");//未执行
}
System.out.println("测试2");//执行了
}
}
- 如果try中遇到了问题 try下面的代码还会执行吗
上述代码输入abc 那么直接执行catch try下面的代码不会执行 当catch代码执行完毕 整个体系的代码执行完毕 继续执行下面的代码
- 如果出现问题没有被捕获
将上述异常换成 NullPointerException 并不是格式异常 输入abc,报错 虚拟机默认处理方式
- 同时出现多个异常
package com.ustc.test10;
import java.util.Scanner;
public class test3 {
public static void main(String[] args) {
try {
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的年龄:");
String age = sc.nextLine();
int age1 = Integer.parseInt(age); //int包装类 直接调用静态方法 parseInt 解析字符串为Int
System.out.println(age1);
System.out.println("测试1"); //执行了
System.out.println(2 / 0);
} catch (NumberFormatException e) {
System.out.println("执行吗");//未执行
}catch (ArithmeticException e){
System.out.println("数学运算异常");
}
System.out.println("测试2");//执行了
}
}
注意: 如果多个异常类出现子父类的关系 父类一定要写在下面,比如Exception 最大的异常类 写在下面
3. 异常处理常见方法
package com.ustc.test10;
public class test11 {
public static void main(String[] args) {
try {
int[] arr = {1,2,3,4,5};
//虚拟机帮助我们创建一个异常对象 这个对象恰好被下面的catch捕获
System.out.println(arr[10]);
} catch (ArrayIndexOutOfBoundsException e) {
//打印异常信息
String message = e.getMessage();
System.out.println(message);
//返回可抛出的简短描述
String s = e.toString();
System.out.println(s);
//将异常的错误信息 输出在控制台
e.printStackTrace(); //打印异常
}
}
}
4. 自定义异常
定义一个异常类,继承RuntimeException 表示继承异常
继承Exception 表示编译异常
package com.ustc.test10;
public class test5 extends RuntimeException{
public test5() {
}
public test5(String message) {
super(message);
}
}
package com.ustc.test10;
public class Student {
private String name;
private int age;
public Student() {
}
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 <= 25)
{
this.age = age;
}
else
{
throw new test5("年龄超出了范围"); //自定义异常类
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}