异常:

概述:java程序运行过程中出现的错误

常见的异常:
StackOverflowError
ArrayIndexOutOfBoundsException
NullPointerException
ClassCastException
ParseException

异常的分类:
Trowable:
  1.--Error: a.相当于天灾人祸,虚拟机出现了问题
  2.--Exception:
    1).RuntimeException:运行过程中出现的异常 可以处理可以不处理,一般出现这种问题都是代码逻辑有问题,推荐修改代码
    2).编译期异常:出发之前因该检查的异常,必须处理,负责编译不通过

1,编译时异常: 除了RuntimeException及其子类,Exception中所有的子类都是,这种异常必须要处理,要不编译通不过。

2,运行时异常 :RuntimeException及其子类都是,这种异常不用处理,编译会通过,不过这样的程序会有安全隐患,遇到这种异常是需要改代码的。

3,严重错误问题 :用Error进行描述,这个问题发生后,一般不编写针对代码进行处理,而是要对程序进行修正.通常都是由虚拟机抛出的问题。

举例说明:

异常分三类:
骑车去旅行:

  Error:走到半路上,发生山路塌陷,或者出现了泥石流,这个问题很严重,不是班长能够立马解决的。

  Exception:出门前,班长要看看车轮子以及车链子等是否还在

  RuntimeException:在骑车的过程中,有好路不走,偏偏要走石子路

异常举例:

 //异常测试:
// a.除数为0
// b.数组越界
public class HomeWork_02 {
public static void main(String[] args) {
System.out.println("start");
f1();
//f2();
System.out.println("end");
}
//数组越界异常
public static void f2(){
int[]arr={1,2,3};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
//System.out.println(arr[3]);//ArrayIndexOutOfBoundsException: 3
}
//除数为0异常
public static void f1(){
int a=23;
int b=0;
System.out.println(a/b);//ArithmeticException: / by zero
}
}

jvm对异常的默认处理:
a. 哪个线程出现的问题
b. 异常的类型以及详细信息
c. 调用栈信息
d. 终止程序

如下图为异常举例代码中数组溢出是jvm所报的错误:



因为jvm处理异常的时候直接停止了程序,所以我们要学会自己处理异常:

如何自己处理异常:
  a. try...catch...finally  
  b. throws



1. try...catch...finally语句
  try {
  要检查的代码
    } catch (异常类型 对象名) {
      对异常的处理
   } finally {
    释放资源
  }
a. 一种异常的情况

 public class ExceptionDemo_03 {
public static void main(String[] args) {
System.out.println("Start");
int a =10;
int b=0;
try{
System.out.println(a/b);
System.out.println("one");
System.out.println("two");
System.out.println("three");
}catch(ArithmeticException e){
System.out.println("除数为0");
System.out.println(e);
}
System.out.println("end");
}
}
//问题:为什么e局部变量会有值? //如果try里面出现了异常, JVM会把异常信息封装成对应类型的异常对象。

 //然后和catch语句依次匹配,找到对应的异常类型,然后把它赋值给引用变量e

输出结果:

注意事项:
a. try里面的代码越少越好,最好只放可能出现异常的代码
b. try里面出现了异常,就不会执行try里面里面后序的代码
c. ArithmeticException e 是局部变量, 作用范围是对应的catch语句。
d. catch 捕获了异常,执行对应的处理,异常就不再存在了。

b.多种异常的情况:
    a. 一个一个处理
    b. 一次性处理
    c. JDK7 新特性
      把多个处理方式相同的catch语句,合成一个catch语句。
        catch(类型1 | 类型2 | 类型3... e)
注意事项:
一个try语句中, 最多只会抛出一个异常,最多也只会执行一个catch语句
如果异常没有兼容惯性,谁先谁后没关系,如果有兼容关系,那么父类应该方法在子类之后。
JDK7新特性, 一个catch 语句不能出现子父类关系

测试代码:

 /*多种异常的情况:
a. 一个一个处理
b. 一次性处理
处理方式相同的catch语句,合成一个catch语句。
catch(类型1 | 类型2 | 类型3... e)*/
public class ExceptiomDemo_04 {
public static void main(String[] args) {
System.out.println("start");
/*try {
f1();
f2();
// f2()在后面的时候,执行到f1()的时候就不再往下执行了,没有输出arr[0],arr[1],arr[2]
} catch (ArithmeticException e) {
// System.out.println("除数为0");
System.out.println("发生了异常");
} catch (ArrayIndexOutOfBoundsException e) {
// System.out.println("数组索引越界");
System.out.println("发生了异常");
} catch (Exception e) {
System.out.println("其他异常");
}*/
try {
f2();
f1();
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("除数为0或者数组索引越界");
} }
public static void f2(){
int []arr={1,2,3};
System.out.println(arr[0]);
System.out.println(arr[1]);
System.out.println(arr[2]);
System.out.println(arr[3]); // ArrayIndexOutOfBoundsException: 3
}
public static void f1(){
int a =10;
int b=0;
System.out.println(a/b);// ArithmeticException: / by zero }
}


编译期异常和运行时异常:
Exception:
  |-- 运行时异常: RuntimeException和其子类。
可以显示处理,也可以不处理,一般出现运行时异常,都是代码逻辑有问题,推荐修改代码逻辑。
  |-- 编译期异常:其他类。无论运行时是否发生异常,都必须显示处理,否则无法通过编译。
测试代码:

 import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone; //编译期异常和运行时异常:
public class ExecptionDemo_05 {
//一般不要在主方法中抛出异常,这里为方便在主方法中抛出异常
public static void main(String[] args) throws ParseException {
//运行时异常:
int a=10;
int b=0;
try{
System.out.println(a/b);
}catch(ArithmeticException e){
System.out.println("除0异常");
}
//编译期异常,不解决不能通过编译
Date time=new Date();
SimpleDateFormat sf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date=sf.format(time);
System.out.println(date);
Date date1=sf.parse(date);//ParseException
}
}


Throwable

Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。

类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

  构造方法摘要: 
    Throwable()
      构造一个将 null 作为其详细消息的新 throwable。
    
Throwable(String message)
      构造带指定详细消息的新 throwable。
  成员方法:
   

      返回此 throwable 的详细消息字符串。

      默认实现:getClass().getName()+“:”+getMessage();
      返回此 throwable 的简短描述。
    void printStackTrace() //推荐使用它,而且输出内容会用红色标识
        将此 throwable 及其追踪输出至标准错误流。

注意:通常e.getMessage()并不能获取全部的错误信息,需要用到e.printStackTrace()查看完整错误信息,但是这个方法是void 只能在控制台输出。

测试代码:

 import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; //Throwable():、
public class ExceptionDemo_06 {
public static void main(String[] args) {
String s = "2001/01/01 00:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try{
date=sdf.parse(s);
}catch(ParseException e){
System.out.println("解析异常");
System.out.println(e.getMessage());
System.out.println(e.toString());
e.printStackTrace();
}
}
}



thorws

定义功能方法时,需要把出现的问题暴露出来让调用者去处理。那么就通过throws在方法上标识。
举例:
村里出现了问题,如果能自己解决就自己解决,解决不掉就交给乡里,乡里解决不掉就抛给县里解决, 县里解决不掉,抛给市里,如果市里解决不掉,抛给省里,如果省里解决不掉,抛给中央。中央就直接干掉。

throws: 把问题抛给调用者
a.编译期异常
b.运行期异常

注意事项:
不要在main()方法抛出异常,如果抛出异常就会执行JVM的默认处理。

测试代码:

 import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class ExceptionDemo_07 {
public static void main(String[] args) {
String s = "2019/7-9 11:31:00";
String pattern = "yyyy-MM-dd HH:mm:ss";
Date date = null;
try {
date = string2Date(s, pattern);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
int a = 10;
int b = 0;
int c = 0;
try {
c = f1(a, b);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("c = " + c);
System.out.println("end");
}
//throw:告诉调用者,注意:调用这个方法可能会有某某异常
public static Date string2Date(String s, String pattern) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
return sdf.parse(s);
}
public static int f1(int a, int b) throws Exception{
// return a / b;
if (b != 0) {
return a / b;
}
throw new Exception("除0异常");
}
}

throw

在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。

测试代码:

throws和throw的区别
throws

用在方法声明后面,跟的是异常类名
可以跟多个异常类名,用逗号隔开
表示抛出异常,由该方法的调用者来处理
throws表示出现异常的一种可能性,并不一定会发生这些异常

throw

用在方法体内,跟的是异常对象名
只能抛出一个异常对象名
表示抛出异常,由方法体内的语句处理
throw则是抛出了异常,执行throw则一定会出现异常, throw抛出了一个实实在在的异常

 import java.util.Scanner;

 //举例:
// 录入学生成绩 [0~100]
public class ExecptionDemo_08 {
public static void main(String[] args) {
System.out.println("请输入学生成绩");
Scanner sr =new Scanner(System.in);
int score=sr.nextInt();
//数据验证
try{
checkScore(score);
}catch(Exception e){
e.printStackTrace(); }
}
public static void checkScore(int score) throws Exception {
if(score<0||score>100){
throw new Exception("score="+score);
}
//throw抛出了异常后,后面的语句就不再执行
System.out.println("one");
System.out.println("two");
System.out.println("three");
}
}



我们到底该怎么处理异常:
原则:如果该方法知道如何处理,那用try...catch, 如果不知道怎么处理,就抛给它的调用者去处理。
区别:
  如果try...catch,后续代码会执行。
  如果throws,后续代码不会被执行。

try语句的变形
try...catch
try...finally
try...catch...finally
try...catch...catch...
try...catch...catch...finally



finally语句:
特点:
  被finally控制的语句体无论出现异常还是没有出现异常,都会执行。
  特殊情况:在执行到finally之前jvm退出了. System.exit();
作用:
  释放系统资源

final和finally和finalize区别:

final: 最终的
  类:不能被继承
  方法:不能被重写
  变量:常量
finally:
  try语句的子句。
  finally里面的语句, 无论出现异常还是不出现异常,都会被执行。  
  用来释放资源。
finalize:
  Object中的方法。
  对象被回收前,该方法会被自动执行。用来释放资源。
  手动调用该方法,对象不会被回收。

 import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class ExceptionDemo_09 {
public static void main(String[] args) {
String s = "2019/7/9 14:40:00";
String pattern = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
try {
Date date = sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
//finally只有在执行到finally之前虚拟机就退出的时候才会不执行
//System.exit(0);
} finally {
System.out.println("finally子句");
}
System.out.println("end");
}
}



如果catch里面有return语句,请问finally的代码还会执行吗?如果会,请问结果是怎样的?
finally语句会被执行
第一次执行return语句,就已经生成了返回路径, 并把返回值保存起来了。
后面在finally语句中修改变量,不会影响返回值。

如果finally中也有return语句。
最终执行的是finally中语句。

 public class ExceptionDemo10 {
public static void main(String[] args) {
System.out.println(method()); //
} public static int method() {
String s = "2019/7/9 14:40:00";
String pattern = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
int a = 10;
try {
a = 20;
Date date = sdf.parse(s);
} catch (ParseException e) {
a = 30;
return a;
} finally {
System.out.println("finally");
a = 40;
return a; //生成了另外一条返回路径
} }
}


自定义异常:
类名就代表异常的种类(信息)
编译期异常:继承Exception
运行时异常:继承RuntimeException

异常类:

 public class ScoreException extends RuntimeException {
public ScoreException(){
super();
}
public ScoreException(String message){
super(message);
}
}

测试类:

 public class EceptionDemo_11 {
public static void main(String[] args) {
System.out.println("请录入学生成绩;");
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
// 数据验证
/*try {
checkScore(score);
// 存入数据库
} catch (ScoreException e) {
e.printStackTrace();
}*/
checkScore(score);
}
private static void checkScore(int score) throws ScoreException{
if (score < 0 || score > 100) {
// throw new RuntimeException("score=" + score);
throw new ScoreException("score=" + score);
}
}
}

异常注意的事项:(编译期异常)
子类重写父类方法时,子类的方法必须抛出相同的异常或父类异常的子类。
如果父类抛出了多个异常,子类重写父类时,只能抛出相同的异常或者是他的子集,子类不能抛出父类没有的异常
如果被重写的方法没有异常抛出,那么子类的方法绝对不可以抛出异常,如果子类方法内有异常发生,那么子类只能try,不能throws

儿子不能比父亲更坏。一代只能比一代强。
编译的时候,不检查运行时异常

Java异常相关知识总结的更多相关文章

  1. 【转】java NIO 相关知识

    原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...

  2. Java 容器相关知识全面总结

    Java实用类库提供了一套相当完整的容器来帮助我们解决很多具体问题.因为我本身是一名Android开发者,包括我在内很多安卓开发,最拿手的就是ListView(RecycleView)+BaseAda ...

  3. java异常基本知识

    Throwable     |--Error     |--Exception         |--RuntimeException                异常体系的特点:异常体系中的所有类 ...

  4. JAVA 异常 基本知识

    异常 异常定义 异常是运行过程中出现的错误 人为错误:填写错误等 随机错误:网络中断.内存耗尽等 一个健壮的程序必须处理各种各样的错误 Java的异常是class Object Throwable E ...

  5. 4)Java容器类相关知识

    1>Array 和 Arrays:   Arrays:用来操作array的工具类,其中包含一组static函数:      equals():比较两个array 是否相等. array拥有相同元 ...

  6. Java GC相关知识

    Java堆的分类 分为两类:YoungGen和OldGen.其中,YoungGen分为三部分:eden,from survivor和to survivor,比例默认是:8:1:1 PermGen不属于 ...

  7. Java继承相关知识总结

    Java继承的理解 一.概念: 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫类的继承 这个新类称为子类,或派生类,已有的那个类叫做父类,或基类 继承的好处:代码得到极大的重用.形成一种类的 ...

  8. Java枚举相关知识

    JAVA枚举 很多编程语言都提供了枚举的概念,但是java直到1.5之后才提出了枚举的概念,出现比这个语言本身晚10年. 主要作用是用于定义有限个数对象的一种结构(多例设计),枚举就属于多例设计并且其 ...

  9. Java——接口相关知识

    1.接口用interface来声明 //定义一个动物接口 public interface Animal{ public void eat(); public void travel(); } 2.接 ...

随机推荐

  1. Jquery绑定事件及动画效果

    Jquery绑定事件及动画效果 本文转载于:https://blog.csdn.net/Day_and_Night_2017/article/details/85799522 绑定事件 bind(ty ...

  2. 阿里Java完整学习资料

    最近有很多读者问我如何系统的进行 Java 学习,于是我就翻阅一下之前收集的资料,分享给大家. 这份资料是我在市面上众多的 Java 学习资料中挑选出来的,相信肯定是精品.而且这份资料是出自阿里,具有 ...

  3. PHP代码篇(七)--PHP及MySQL已经使用过的函数

    一.PHP常用函数 //数组转字符串 $str = implode(',',$device_string); //字符串转数组 $arr = explode(',',$device_string); ...

  4. 8.python3实用编程技巧进阶(三)

    3.1.如何实现可迭代对象和迭代器对象 #3.1 如何实现可迭代对象和迭代器对象 import requests from collections.abc import Iterable,Iterat ...

  5. emacs 帮助相关命令

    emacs 帮助相关命令 如下表: No. 键盘操作 键盘操作对应的函数 回答的问题 01 ctrl-h c describe-key-briefly 这个按键组合将运行哪个函数 02 ctrl-h ...

  6. [Go] gocron源码阅读-判断是否使用root用户执行

    判断是linux系统,并且uid为0,allowRoot是通过命令行传参传进来的,通过flag包解析出来的,可以使用go run node.go -h看到这些参数 && !allowR ...

  7. Docker 类面试题(常见问题)

    Docker 常见问题汇总   镜像相关 1.如何批量清理临时镜像文件? 可以使用sudo docker rmi $(sudo docker images -q -f danging=true)命令 ...

  8. Python的3种执行方式

    1.Python源程序就是一个特殊格式的文本文件,可以使用任意文本编辑器软件做python的开发,python的文件扩展名为 .py   2.执行python程序的三种方式 解释器:用命令行输入:如输 ...

  9. mongodb的数据库,集合,数据可介绍。

    我们知道,在关系型数据库里面有数据库.数据表.表里面是一行一行的数据.而mongodb是非关系型数据库,它有的是数据库.集合.文档,分别对应关系型里面的数据库.数据表.和表里面一行一行的数据.在mon ...

  10. 剑指Offer-14.链表中倒数第k个结点(C++/Java)

    题目: 输入一个链表,输出该链表中倒数第k个结点. 分析: 第一个解法,我们可以先遍历一遍链表,计算下节点的总数n,然后再从头结点查n-k个节点,即是倒数第k个节点. 第二个解法,便是使用双指针,两个 ...