Java异常相关知识总结
异常:
概述: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异常相关知识总结的更多相关文章
- 【转】java NIO 相关知识
原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...
- Java 容器相关知识全面总结
Java实用类库提供了一套相当完整的容器来帮助我们解决很多具体问题.因为我本身是一名Android开发者,包括我在内很多安卓开发,最拿手的就是ListView(RecycleView)+BaseAda ...
- java异常基本知识
Throwable |--Error |--Exception |--RuntimeException 异常体系的特点:异常体系中的所有类 ...
- JAVA 异常 基本知识
异常 异常定义 异常是运行过程中出现的错误 人为错误:填写错误等 随机错误:网络中断.内存耗尽等 一个健壮的程序必须处理各种各样的错误 Java的异常是class Object Throwable E ...
- 4)Java容器类相关知识
1>Array 和 Arrays: Arrays:用来操作array的工具类,其中包含一组static函数: equals():比较两个array 是否相等. array拥有相同元 ...
- Java GC相关知识
Java堆的分类 分为两类:YoungGen和OldGen.其中,YoungGen分为三部分:eden,from survivor和to survivor,比例默认是:8:1:1 PermGen不属于 ...
- Java继承相关知识总结
Java继承的理解 一.概念: 一个新类从已有的类那里获得其已有的属性和方法,这种现象叫类的继承 这个新类称为子类,或派生类,已有的那个类叫做父类,或基类 继承的好处:代码得到极大的重用.形成一种类的 ...
- Java枚举相关知识
JAVA枚举 很多编程语言都提供了枚举的概念,但是java直到1.5之后才提出了枚举的概念,出现比这个语言本身晚10年. 主要作用是用于定义有限个数对象的一种结构(多例设计),枚举就属于多例设计并且其 ...
- Java——接口相关知识
1.接口用interface来声明 //定义一个动物接口 public interface Animal{ public void eat(); public void travel(); } 2.接 ...
随机推荐
- webpack打包配置禁止html标签全部转为小写
用webpack打包页面,发现html中特别写的用来给后端识别的大写标签全部被转为了小写标签,这时候需要将加一个配置 ,caseSensitive:true ,禁止大小写转换. webpack配置: ...
- 被公司的垃圾XG人事系统吓尿了
OA要尝试设置单点登录,拿现有的HR系统尝试,结果不知道HR系统的加密方式和验证地址,于是乎找HR厂商——厦门XG软件实施人员.结果那个技术人员支支吾吾不肯给我,搞得非常的烦. 真奇怪了,不开源的软件 ...
- Microsoft.Extensions.DependencyInjection 阅读笔记
一. 关于IServiceCollection接口的设计 public interface IServiceCollection : IList<ServiceDescriptor> { ...
- python pyinstaller 模块的基本使用
作用 PyInstaller是一个压缩python文件成为可执行程序的一个软件.它会扫描你所有的Python文档,并分析所有代码从而找出所有你的代码运行所需的模块.然后,PyInstaller会将所有 ...
- Windows 压缩文件到 Linux中解压文件名乱码
问题 在Windows中将文件夹压缩后,拿到Ubuntu系统中解压,中文文件名乱码 解决 因为两个系统所使用的编码不同,Windows一般使用GBK编码,Ubuntu使用utf8编码,只需要在解压的时 ...
- C++学习三 模板类出错总结(Missing template arguments before 'L')
一.模板类的说明 模板类有一个好处是可以放宽你输入的数据类型. 比如有这样的一个函数: int add(int x, int y) { return x+y; } 这个函数对于int类型的x,y才适合 ...
- Jmeter Question 之 ‘批量执行SQL语句’
第一步: MySql数据库:jdbc:mysql://ip:3306/数据库名?useUnicode=true&characterEncoding=utf8&allowMultiQue ...
- Vue+cordova开发App
Vue+cordova开发App https://www.imooc.com/article/70062
- 解决Django-Error: That port is already in use
Error: That port is already in use. 1.使用python manage.py runserver 8001 开一个新的端口. 2.kill掉原来的端口(在root条 ...
- CentOS7 通过 devstack 安装 OpenStack
安装前的准备 修改源 (可跳过) 将下载源变更到国内可以时下载速度大大提升 打开下面的文件 vim /etc/yum.repos.d/CentOS-Base.repo 将原来的注释掉改成: [base ...