年前规划
JavaSE高级
异常
集合
IO
网络编程
反射
Java8+新特性
Linux 操作系统
Oralce
第一阶段项目:基于Swing
异常
Error:错误,不能解决,是由于硬件或者JVM发生的不正常情况
Exception:程序的异常,是我们可以解决和处理的问题,往往发生的原因在于代码上。
异常分类
编译期异常(检查异常):编译期被检查发现的异常,必须处理,若不处理,程序不能运行。网络或者文件导致的。
运行期异常(非检查异常):编译期不会被检查,只有运行时才会进行检查的异常。由程序逻辑错误引起的。
异常的定义
一场就是在程序编译和运行期间,所产生的一种不正常结果;
异常指程序运行过程中出现的非正常现象,例如用户输入错误、除数为零、需要处理的文件不存在、数组下标越界等。
在 Java 的异常处理机制中,引进了很多用来描述和处理异常的类,称为异常类。
异常类定义中包含了该类异常的信息和对异常进行处理的方法。
所谓异常处理,就是指程序在出现问题时依然可以正确的执行完。
常见的RunTimeException
// 运行时异常
// IndexOutOfBoundsException
int[] arr = new int[5];
System.out.println(arr[5]);
//空指针异常 NullPointException
String str = null;
System.out.println(str.equals("abc"));
// 类型转换异常 ClassCastException
Object obj = new String();
Integer inte = (Integer) obj;
// 算术异常
System.out.println(1/0);
// 解析异常
String strDate = "2020-12-23";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(strDate); // 有可能发生异常 必须处理不处理程序无法正常执行
System.out.println(date);
异常对程序产生的影响
当发生异常的时候 程序就会终止,异常代码之后的 程序将不在执行。
异常的处理
编译期异常和运行时异常的区别:
1. 运行时异常不处理,不会影响程序的运行,而运行期异常则必须做出相应的处理,否则程序无法运行。
2. 运行时异常往往都可以通过优化代码来进行规避,运行时异常的出现,都是我们的程序存在逻辑上的漏斗或者缺陷。
在实际处理中 处理的重点编译期异常
Java中对异常的处理,提供了一种异常处理模型——抓抛模型
捕获异常
try{
包含有可能异常的代码;
}catch(异常类型 变量){
针对这种异常的处理;
}finally{
无论程序是否异常,都需要执行的代码;
}
// 解析异常 ParseException
String strDate = "2020-12-23 " ;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;// 有可能发生异常 必须处理 不处理程序无法正常执行
try {
date = sdf.parse(strDate);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
通过catch捕获异常,并对异常做出相应的处理 这样就可以保证程序继续执行
可以同时有多个catch块
try {
System.out.println(arr[5]);
System.out.println(str.equals("abc"));
Integer inte = (Integer) obj;
System.out.println(1/0);
date = sdf.parse(strDate);
} catch (ParseException e) {
System.out.println("异常处理");
e.printStackTrace();
}catch (ArrayIndexOutOfBoundsException ae) {
System.out.println("处理数组下标越界异常");
}catch (NullPointerException ne){
System.out.println("处理空指针异常");
}
多异常捕获
try {
Integer inte = (Integer)obj;
System.out.println(arr[5]);
System.out.println(str.equals("abc"));
System.out.println(1/0);
date = sdf.parse(strDate);
} catch (ParseException |ArrayIndexOutOfBoundsException |NullPointerException e) {
System.out.println("异常处理");
e.printStackTrace();
}
通过异常的多态来捕获
try {
System.out.println(arr[5]);
System.out.println(str.equals("abc"));
Integer inte = (Integer)obj;
System.out.println(1/0);
date = sdf.parse(strDate);
} catch (Exception e) {
System.out.println("异常处理");
// e.printStackTrace();
}
这种写法仅限于jkd7以上
可以这样写。
try {
Integer inte = (Integer)obj;
System.out.println(arr[5]);
System.out.println(str.equals("abc"));
System.out.println(1/0);
date = sdf.parse(strDate);
} catch (ParseException e) {
System.out.println("异常处理");
e.printStackTrace();
}catch (ArrayIndexOutOfBoundsException ae){
}catch (NullPointerException ne){
}catch (Exception ee){
}
捕获异常 将有可能发生异常的代码写在try块中,当发生异常的时候 ,就会执行相应的catch块的内容 可以保证异常处理之后的代码的正常执行,从而使得程序可以正常终止
在程序设计时,只需将有可能发生异常的代码放在try块中,而不要将没有异常发生的代码添加到try,这样会影响程序的执行的效率
异常信息的分析
异常信息的描述
在异常体系中,所有的子类都没有具体方法,方法都是来自于Throwable
} catch (ParseException e) {
System.out.println("异常处理");
e.printStackTrace();
}catch (ArrayIndexOutOfBoundsException ae){
System.out.println("数组下标越界");
ae.printStackTrace();
String message = ae.getMessage();//Index 5 out of bounds for length 5
System.out.println(message);
}catch (NullPointerException ne){
ne.printStackTrace();
}catch (Exception ee){
ee.printStackTrace();//得到的异常的全部信息
String msg= ee.toString();
System.out.println(msg);
}
第二种处理方式:抛出异常
//将String类型转换为Date 解析
public static Date str2Date(String strDate) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(strDate);
return date;
}
抛出异常是在方法的声明上,通过throws 关键字来进行声明
告诉方法的调用者,该方法存在这样类型的异常,throws后边跟的是异常类型。
//将String类型转换为Date 解析
public static Date str2Date(String strDate) throws ParseException, IOException {
File file = new File("src/str.txt");
file.delete();
file.canWrite();
file.getCanonicalPath();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(strDate);
return date;
}
在throws后边可以跟多个类型异常
抛出异常是抛给了方法的调用者,此时对于方法的调用者来说将有两种选择:
第一种使用try{}catch{}来捕获异常并处理
第二种则是不处理,继续使用throws往外抛
JVM对于接受到的异常的默认处理
以上就是jvm的默认处理方式:
就是打印异常的堆栈信息,并终止程序的执行。
对于与业务相关的异常,就需要我们自己来定义异常
自定义异常
有一个考试系统,需要老师来录入学生的考试成绩 ,如果老师录入的成绩是0-100则为正常,负责就抛出一个成绩不合法的异常信息。
如何自定义异常:
自定义异常就两种:
1. 一种是自定义编译期异常
2. 另一种就是定义运行时异常
如果要自定义个一个编译期异常 则继承Exception即可 并实现相应的构造方法即可
如果要自定义一个运行时异常 则继承RuntimeException 并实现相应的构造方法
//自定义一个成绩异常
public class ScoreException extends Exception{
public ScoreException(){
super();
}
//message表示显示的错误信息
public ScoreException(String message){
super(message);
}
}
public class Teacher {
public void recoderScore(int score) throws ScoreException {
if(score >0 && score <=100){
System.out.println("本次录入的成绩为:" + score);
}else{
// 手动抛出异常
throw new ScoreException("成绩不合法");
}
}
public static void main(String[] args) throws ScoreException {
Teacher teacher = new Teacher();
teacher.recoderScore(180);
}
}
throw和throws的区别★
1. 位置:
throws用在方法的声明上
throw在方法体
2. 抛出类型
throws抛出的是 异常的类型
throw抛出的是异常对象
3. 数量
throws可以抛出多个异常
throw只能抛出 一个异常对象
什么时候抓?什么时候抛?★
捕获异常都在我们可以自己处理并且处理之后不会再次产生新的异常时,才捕获处理。
如果不能完全处理异常,则将异常抛出给下一个方法的调用者,让其来做出相应的处理,直到最后抛给jvm