声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点+题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!)
人遇到问题而停止脚步,解决问题后,继续前行。
程序在自上而下执行的时候,发生了不可预期的事件,这个事件阻止程序的运行。这就是异常。
比如:数组下标越界、类转换异常。
Java给咱们封装很多的异常类,并且提供很优秀的异常处理机制。
其中Java提供了一个类Throwable
小tips:
学习一个新的类的时候,自己看官方文档,主要看构造方法和成员方法
学着多使用API帮助文档:Java 8 中文版 - 在线API手册 - 码工具(在线文档)
ctrl+F打开搜索栏
Throwable()构造一个新的可抛出的null作为其详细信息。 |
Throwable(String message)构造一个具有指定的详细消息的新的throwable。 |
返回值类型 | 方法名+作用 |
String | getMessage() 返回此throwable的详细消息字符串。 |
void | printStackTrace() 将此throwable和其追溯打印到标准错误流。打印出标准输出流信息 |
String | toString()返回此可抛出的简短描述。toString里的是标准输出流的一部分 |
public class Demo1 {
public static void main(String[] args) {
System.out.println("嘻嘻");
System.err.println("哈哈");
Throwable throwable = new Throwable();
System.out.println(throwable.getMessage());
Throwable throwable2 = new Throwable("哈哈,我傻逼了");
System.out.println(throwable2.getMessage());
/**
* java.lang.Throwable: 哈哈,我傻逼了
at com.qfedu.b_trhowable.Demo1.main(Demo1.java:7)
*/
throwable2.printStackTrace();
//java.lang.Throwable: 哈哈,我傻逼了
//告知了这个错误信息
System.out.println(throwable2.toString());
}
}
Throwable 下面有两个子类 一个叫Error(错误) 一个叫Exception(异常)
是代表JVM本身的错误,咱们程序员是通过代码解决不了的。
异常,代表程序在运行过程中,发生了不可预期的事件。可以使用Java来出来,让他继续执行下去。
FileNotFoundException | 文件找不到异常 |
SQLException | SQL语句异常 |
ClassNotFoundException | 类找不到异常 |
InterruptException | 中断异常 |
ArrayIndexOutOfBoundException | 数组下标越界 |
ClassCastException | 类转换异常 |
NullPointerException | 空指针异常 |
区分好编译时异常和运行时异常,一般来说,程序运行后才报错的都是运行时异常
另外异常作为Throwable的子类,也是可以使用父类的相应方法的
public class Main {
public static void main(String[] args) {
Exception exception=new Exception();
Exception exception1=new Exception("嘻嘻嘻");
exception1.printStackTrace();
System.out.println(exception1.toString());
System.out.println(exception1.getMessage());
}
输出:
java.lang.Exception: 嘻嘻嘻
at org.example.Main.main(Main.java:991)
java.lang.Exception: 嘻嘻嘻
嘻嘻嘻
当代码出现异常时,java提供了两种解决方法
1.异常的捕捉
2.异常的抛出
在程序运行过程中,代码难免有可能会遇到异常。如果没有异常,代码正常执行。如果有异常,就捕捉异常
try {
有可能出现异常的代码
} catch (异常对象) {
//针对于上面异常的处理方案
public class Demo2 {
public static void main(String[] args) {
test(3, 0);
}
public static void test (int a, int b) {
int ret = 0;
try {
//有可能个出现异常的代码
ret = a / b;
} catch (ArithmeticException e) {
System.out.println("123");
//打印错误信息
System.out.println(e.getMessage());
}
//即使代码有异常,通过捕捉以后。是不会影响程序的接着执行的代码的
System.out.println(ret);
System.out.println( 4 + 4);
}
}
//即使代码有异常,通过捕捉以后。是不会影响程序的接着执行的代码的
其实try-catch语句,就相当于是一个if-else语句,如果try里面的代码出问题了,就执行catch里的处理方法,此时try里的代码就相当于没用了,如果try里的代码没问题,就不会执行catch里的代码,大家可以通过上述示例代码进行验证
如果说出现多个异常呢?
jvm虚拟机不会每个异常都执行,先检测到哪个异常,就直接执行哪个异常的catch代码了
我们用一段代码来感受这个过程
1.最开始这段代码里,如果test(1,0,arr),就会执行打印123的异常,如果是现在的test(1,1,arr),就会执行打印456的异常
public class Demo3 {
public static void main(String[] args) {
int[] arr = new int[2];//数组的容量是2
test(1, 1, arr);
}
public static void test (int a, int b, int[] arr) {
int ret = 0;
try {
ret = a / b;//有可能出现的异常的代码
arr[2] = 89;//这个会有异常
//jvm造出来哪个异常对象,就去catch 到哪个异常然后去执行具体的catch
} catch (ArithmeticException e) {
System.out.println("123");
System.out.println(e.getMessage());
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("456");
System.out.println(e.getMessage());
}
System.out.println(4 + 8);
}
}
2.然后改进一下,把异常写在一起,先检测到哪个就先执行哪个
public class Demo4 {
public static void main(String[] args) {
int[] arr = new int[2];//数组的容量是2
test(1, 1, arr);
}
public static void test (int a, int b, int[] arr) {
int ret = 0;
try {
ret = a / b;//有可能出现的异常的代码
arr[2] = 89;//这个会有异常
//jvm造出来哪个异常对象,就去catch 到哪个异常然后去执行具体的catch
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("123");
System.out.println(e.getMessage());
}
System.out.println(4 + 8);
}
}
3.再改进一下,之前说了,这些异常的父类都是Exception,所以直接用Exception,相当于是子类的异常类型赋值给了父类对象,多态的实际使用
public class Demo5 {
public static void main(String[] args) {
int[] arr = new int[2];//数组的容量是2
test(1, 0, arr);
}
public static void test (int a, int b, int[] arr) {
int ret = 0;
try {
ret = a / b;//有可能出现的异常的代码
arr[2] = 89;//这个会有异常
//jvm造出来哪个异常对象,就去catch 到哪个异常然后去执行具体的catch
} catch (Exception e) {
System.out.println("123");
System.out.println(e.getMessage());
}
System.out.println(4 + 8);
}
}
4.最后介绍一下finally语法,就是可以放在catch后面,不管有没有异常都会执行,但是呢,实际上即使没有finally,后面的代码也会执行,所以实际用处不大,知道有这个就行
public class Demo5 {
public static void main(String[] args) {
int[] arr = new int[2];//数组的容量是2
test(1, 0, arr);
}
public static void test (int a, int b, int[] arr) {
int ret = 0;
try {
ret = a / b;//有可能出现的异常的代码
arr[2] = 89;//这个会有异常
//jvm造出来哪个异常对象,就去catch 到哪个异常然后去执行具体的catch
} catch (Exception e) {
System.out.println("123");
System.out.println(e.getMessage());
} finally {
//无论有没有异常,最终都要执行的
System.out.println(4 + 8);
}
}
}
不知道通过上面这个代码逐渐改进的过程,大家有没有理解到jvm虚拟机的异常处理机制,如果没有,就再多看几次代码,跟着代码跑一跑。这个不难,应该要能理解。
在代码出现异常的地方进行异常的抛出,如果异常的抛出的话,一旦发生异常,从出现异常的地方会终止代码。
throw | 在方法中抛出一个异常。自己造一个错 |
throws | 在方法的声明处书写,告知当前调用者,此处有异常。要小心 |
区别 | throw的是异常的对象,是主动抛出异常给jvm虚拟机让其报错,同时throw往往是运行时异常抛出,可以直接在函数体内声明,而throws则往往是编译时异常抛出,需要先在函数体外声明 |
以后实际开发中是发生错误后主动抛出一个异常,会设置一个全局异常处理器,去主动抓取这个异常,再进行处理,比如,登录事件,如果密码错误,抛出异常,全局异常处理器抓取这个异常,然后返回给前端一个错误json格式数据,前端再弹出密码错误窗口
import java.io.FileNotFoundException;
public class Demo8 {
public static void main(String[] args) throws Exception{
test(0);
Thread.sleep(1000);
}
public static void test (int a) throws FileNotFoundException{
if (a == 0) {
//编译时异常
throw new FileNotFoundException();
}
System.out.println("jvm xixi");
}
}
关于异常:一阶段和二阶段 只需要会咋抛的或者咋捕捉的即可.要么用try-catch,要么用throw
Java给咱们提供了很多的异常对象,但是有的时候还是满足不了现实生活的需求,所以出现自己造异常对象。但是记住:一定要继承Exception!
public class Demo11 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int score = scanner.nextInt();
try {
test(score);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public static void test (int score) throws Exception {
if (score > 100 || score < 0) {
throw new Exception("输入的整数有误的。。。");
}
if (score >= 90 && score <= 100) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 70) {
System.out.println("及格");
} else {
System.out.println("叫家长。。。");
}
}
}
不过实际上,我们都不需要自己定义异常,与其继承Exception,干嘛不直接用Exception呢?
以上就是今天所有的知识点,其实不止,但是异常的知识点有点多,想了想今天就先写异常,大家先把这个知识点吃下再说,异常最开始看着代码多,其实不难,用多了就习惯了。
今天的没有习题,大家多看多写多理解,把示例吃透就好。