一、异常
1.1 异常 :指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象。Java处理异常的方式是中断处理。
1.2 异常体系:异常机制其实是帮助我们找到程序中的问题,异常的根类是 java.lang.Throwable ,其下有两个子类:java.lang.Error与java.lang.Exception ,平常所说的异常指 java.lang.Exception。
Error:无法通过处理的错误,只能事先避免,好比绝症。
Exception:表示异常,异常产生后程序员可以通过代码的方式纠正,使程序继续运行,是必须要处理的。好比感冒、阑尾炎。
1.3 Throwable中的常用方法:
public void printStackTrace() :打印异常的详细信息,包含了异常的类型,异常的原因,还包括异常出现的位置,在开发和调试阶段,都得使用printStackTrace。
public String getMessage() :获取发生异常的原因。提示给用户的时候,就提示错误原因。 public String toString() :获取异常的类型和异常描述信息(不用)。
1.4 异常分类:
1、编译时期异常:checked异常。在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常)
2、运行时期异常:runtime异常。在运行时期检查异常,在编译时不报错(如数学异常)
二、异常的处理
2.1 在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
2.1.1 throw使用格式: throw new 异常类名(参数);
2.1.2 throw使用举例:
throw new NullPointerException("要访问的arr数组不存在");
throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");
2.2 Objects非空判断:
public static T requireNonNull(T obj) :查看指定引用对象是不是null,如果为null则抛出异常。
2.3 声明异常throws:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理,那么必须通过throws进行声明,让调用者去处理。 关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常)。
2.3.1 throws使用格式:
修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2…{ }
2.3.2 throws代码演示:
2.3.2 throws使用注意事项:
1、throws用于进行异常类的声明,若该方法可能有多种异常情况产生,那么在throws后面可以写多个异常类,用逗号隔开。
2.4 捕获异常try…catch
2.4.1 使用格式:
2.4.2 使用举例:
2.5 finally 代码块:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。
2.5.1 使用格式:
2.5.2 注意事项:finally不能单独使用。
2.6 异常注意事项
2.6.1 多个异常使用捕获又该如何处理呢? 一般我们是使用一次捕获多次处理方式,格式如下:
注意事项:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求在上面的catch处理,父类异常在下面的catch处理。
2.6.2 运行时异常被抛出可以不处理。即不捕获也不声明抛出。
2.6.3 避免在finally中使用return语句。
2.6.4 父类抛出什么异常,子类就抛出什么异常。
三、自定义异常
3.1 什么是自定义异常类: 在开发中根据自己业务的异常情况来定义异常类。
3.2 异常类如何定义:
1. 自定义一个编译期异常: 自定义类 并继承于 java.lang.Exception 。
2. 自定义一个运行时期的异常类:自定义类 并继承于 java.lang.RuntimeException 。
3.3 自定义异常类的练习
定义一个登陆异常类RegisterException:
四、多线程
4.1 并发与并行:
并发:指两个或多个事件在同一个时间段内发生(交替发生)。
并行:指两个或多个事件在同一时刻发生(同时发生)。
4.2 线程与进程
进程:是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。
4.3 线程调度:
分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
抢占式调度 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。
4.4 创建线程类
4.4.1 Java使用 java.lang.Thread 类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用实际上就是执行一段顺序执行的代码。
4.4.2 Java中通过继承Thread类来创建并启动多线程的步骤如下:
1. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把 run()方法称为线程执行体。
2. 创建Thread子类的实例,即创建了线程对象
3. 调用线程对象的start()方法来启动该线程
4.4.3 代码演示: