Java从零开始学十九(异常)
一、什么是异常
从字面上讲,就是不正常的现实就是异常。
程序中的异常也是要在程序运行中才会偶尔发生。如果程序还没有运行,编译就报错,这种不叫异常,这种叫编译错误,通常是语法上的错误
二、java中异常
Java 提供了两类主要的异常:runtime exception 和checked exception。所有的checked exception 是从java.lang.Exception 类衍生出来的,而
runtime exception 则是从java.lang.RuntimeException 或java.lang.Error类衍生出来的。它们的不同之处表现在两方面:机制上和逻辑上
所有异常必须处理!在程序里可以抛异常,但是决不能把异常抛给最终用户。
BUG 在程序员手里还不是BUG,但是一旦交付,那么就是BUG
2.1、机制上
runtime exceptions:
- 在定义方法时不需要声明会抛出runtime exception
- 在调用这个方法时不需要捕获这个runtime exception
- runtime exception 是从java.lang.RuntimeException 或
- java.lang.Error 类衍生出来的。
checked exceptions:
- 定义方法时必须声明所有可能会抛出的checked exception
- 在调用这个方法时,必须捕获它的checked exception,不然就得
- 把它的exception 传递下去
- checked exception 是从java.lang.Exception 类衍生出来的
2.2、逻辑上
从逻辑的角度来说,checked exceptions 和runtime exception 是有不同的使用目的的。
checked exception 用来指示一种调用方能够直接处理的异常情况。checked exception 迫使你捕获它并处理这种异常情况。
而runtime exception 则用来指示一种调用方本身无法处理或恢复的程序错误。
三、程序中看异常
3.1、例一
package com.pb.demo6; import java.util.Scanner; /*
* 求2个整数的商
* 当异常发生时,程序如何处理
*/
public class Test1 { public static void main(String[] args) {
//从键盘获得输入
Scanner input=new Scanner(System.in);
System.out.println("请输入被除数:");
int num1=input.nextInt();
System.out.println("请输入除数:");
int num2=input.nextInt();
int result=num1/num2;
System.out.println(num1+"与"+num2+"的商: "+result);
System.out.println("谢谢使用!"); } }
当输入除数不是0时,正常运行,但当输入的除数为0时,或者字符串时,就会报出异常:
请输入被除数:
2
请输入除数:
0
Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.pb.demo6.Test1.main(Test1.java:18)
请输入被除数:
ffd
Exception in thread "main" java.util.InputMismatchException
同时也发现有异常发生时,最后的输出语句并没有执行
四、常见异常
java.lang.ArithmeticExecption
算术异常类。当出现异常的运算条件时,抛出此异常。比如程序中出现了“除以零”这样的运算,就会出这样的异常。对这种异常,大家就要好好检查一下自己程序中,涉及到数学运算的地方,公式是不是有不妥了
java.lang.NullPointerException
空指针异常类。简单地说就是调用了未经初始化的对象或者是不存在的对象。当应用程序试图在需要对象的地方使用null 时,抛出该异常这种情况包括:
- 调用null 对象的实例方法
- 访问或修改null 对象的字段
- 将null 作为一个数组,获得其长度
- 将null 作为一个数组,访问或修改其时间片
- 将null 作为Throwable 值抛出
应用程序应该抛出该类的实例,指示其他对null 对象的非法使用
java.lang.ClassNotFoundException
找不到类异常。当应用程序试图使用以下方法通过字符串名加载类时,抛出该异常:
- Class 类中的forName 方法
- ClassLoader 类中的findSystemClass 方法
- ClassLoader 类中的loadClass 方法
java.lang.ArrayIndexOutOfBoundsException
数组下标越界异常。用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引
现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常
java.lang.IllegalArgumentException
方法的参数错误异常。抛出的异常表明向方法传递了一个不合法或不正确的参数
类库中的方法在一些情况下都会引发这样的错误,比如音量调节方法中的音量参数,如果写成负数就会出现这个异常,再比如g.setColor(int red,intgreen,int blue)这个方法中的三个值,如果有超过255 的也会出现这个异常因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误
java.lang.IllegalAccessException
没有访问权限异常。当应用程序试图反射性地创建一个实例(而不是数组)、设置或获取一个字段,或者调用一个方法,但当前正在执行的方法无法访问指定类、字段、方法或构造方法的定义时,抛出该异常对程序中用了package 的情况下要注意这个异常
java.lang.IncompatibleClassChangeError
不兼容的类变化错误。当正在执行的方法所依赖的类定义,发生了不兼容的改变时,抛出该错误一般在修改了应用中的某些类的声明定义,而没有对整个应用重新编译,而直接运行的情况下,容易引发该错误
java.lang.InstantiationError
实例化错误。当应用程序试图使用Java 的new 结构,来实例化一个抽象类或一个接口时,抛出该异常通常由编译器捕获此错误,如果类定义中存在不兼容的更改,则此错误
将只可能发生在运行时
java.lang.LinkageError
链接错误。该错误及其所有子类指示一个类在一定程度上依赖于另一个类;但是,在编译前一个类之后,后一个类发生了不相容的改变
java.lang.StackOverflowError
堆栈溢出错误。当一个应用递归调用的层次太深,而导致堆栈溢出时,抛出该错误
java.lang.NumberFormatException
数字格式异常。当试图将一个String 转换为指定的数字类型,而该字符串却不满足数字类型要求的格式时,抛出该异常
java.lang.RuntimeException
运行时异常。RuntimeException 是那些可能在Java 虚拟机正常运行期间抛出的异常的超类可能在执行方法期间抛出但未被捕获的RuntimeException 的任何子类,都无需在throws 子句中进行声明
java.io.IOException
输入输出异常。当发生某种I/O 异常时,抛出此异常。此类是失败或中断的I/O 操作生成的异常的通用类
java.io.FileNotFoundException
文件未找到异常。当试图打开指定路径名表示的文件失败时,抛出此异常
在不存在具有指定路径名的文件时,此异常将由FileInputStream、FileOutputStream 和RandomAccessFile 构造方法抛出。如果该文件存在,但是由于某些原因不可访问,比如试图打开一个只读文件进行写入,则此时这些构造方法仍然会抛出该异常
java.io.EOFException
文件已结束异常。当输入过程中意外到达文件或流的末尾时,抛出此异常
此异常主要被数据输入流用来表明到达流的末尾。注意,其他许多输入操作返回一个特殊值表示到达流的末尾,而不是抛出异常
java.lang.InterruptedException
被中止异常。当线程在活动之前,或活动期间处于正在等待、休眠或占用状态,且该线程被中断时,抛出该异常有时候,一种方法可能希望,测试当前线程是否已被中断,如果已被中断,则立即抛出此异常
五、异常处理
5.1、语法格式:
try{
// 有可能出现异常的语句
}catch(异常类 异常对象){
// 编写异常的处理语句
}[ catch(异常类 异常对象){
// 编写异常的处理语句
} catch(异常类 异常对象){
// 编写异常的处理语句
} …. ]
[finally{
一定会运行到的程序代码 ;
}
主要搭配:try-catch、try-catch-finally、try-finally三种形式
5.2、多个异常
如果同时有多个catch块,Exception 必须放在最后一个catch块中
package com.pb.demo6; import java.util.InputMismatchException;
import java.util.Scanner; import javax.naming.AuthenticationException; /*
* 求2个整数的商
* 当异常发生时,程序如何处理
*/
public class Test1 { public static void main(String[] args) {
//从键盘获得输入
try{
Scanner input=new Scanner(System.in);
System.out.println("请输入被除数:");
int num1=input.nextInt();
System.out.println("请输入除数:");
int num2=input.nextInt();
int result=num1/num2;
System.out.println(num1+"与"+num2+"的商: "+result);
}catch(InputMismatchException e){
System.out.println("输入的不是数字");
e.printStackTrace(); }catch(ArithmeticException e){
System.out.println("除数不能为0");
e.printStackTrace();
}catch(Exception e){
System.out.println("其它错误!");
e.printStackTrace();
}finally{
System.out.println("谢谢使用!");
} } }
请输入被除数:
2
请输入除数:
0
除数不能为0
java.lang.ArithmeticException: / by zero
at com.pb.demo6.Test1.main(Test1.java:22)
谢谢使用!
在finally中的语句,不管出不出异常都会被执行.
但如果在catch块中:执行System.exit(0);或者System.exit(-1);程序将直接结束,finally中的语句将不会执行
5.3、Java的异常处理机制
- 一旦产生异常,则首先会产生一个异常类的实例化对象;
- 在try语句中对此异常对象进行捕捉;
- 产生的异常对象与catch语句中的各个异常类型进行匹配,如果匹配成功,则执行catch语句中的代码
六、抛出异常
6.1、throws关键字
package com.pb.demo6; import java.util.InputMismatchException;
import java.util.Scanner; import javax.naming.AuthenticationException; /*
* 求2个整数的商
* 当异常发生时,程序如何处理
*/
public class Test2 { public static void main(String[] args) {
try {
divide();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } //除法运算
public static void divide () throws Exception{
//从键盘获得输入
Scanner input=new Scanner(System.in);
System.out.println("请输入被除数:");
int num1=input.nextInt();
System.out.println("请输入除数:");
int num2=input.nextInt();
int result=num1/num2;
System.out.println(num1+"与"+num2+"的商: "+result);
}
}
6.2、throw关键字
package com.pb.demo6;
/*
* 人类
*/
public class Person {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) throws Exception {
if(sex.equals("男") || sex.equals("女")){
this.sex = sex;
}else{
throw new Exception("性别只能是男或者女");
} }
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>=0 && age<=150){
this.age = age;
}else{
try {
throw new Exception("年龄只能在0-150岁之间!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void printSelf(){
System.out.println("姓名:"+this.name+" 性别:"+this.sex+" 年龄:"+this.age);
} }
package com.pb.demo6; public class PersonTest { public static void main(String[] args) {
Person p=new Person(); try {
p.setName("张三");
p.setSex("不男不女");
p.setAge(200);
p.printSelf();
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
} } }
七、自定义异常
package com.pb.demo6; public class MyException extends Exception { public MyException() {
super();
// TODO Auto-generated constructor stub
} public MyException(String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
// TODO Auto-generated constructor stub
} public MyException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
} public MyException(String message) {
super(message);
// TODO Auto-generated constructor stub
} public MyException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
} }
package com.pb.demo6;
/*
* 人类
*/
public class Person {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) throws Exception {
if(sex.equals("男") || sex.equals("女")){
this.sex = sex;
}else{
throw new MyException("性别只能是男或者女");
} }
public int getAge() {
return age;
}
public void setAge(int age) {
if(age>=0 && age<=150){
this.age = age;
}else{
try {
throw new MyException("年龄只能在0-150岁之间!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void printSelf(){
System.out.println("姓名:"+this.name+" 性别:"+this.sex+" 年龄:"+this.age);
} }
package com.pb.demo6; public class PersonTest { public static void main(String[] args) {
Person p=new Person(); try {
p.setName("张三");
p.setSex("不男不女");
p.setAge(200);
p.printSelf();
} catch (Exception e) {
e.getMessage();
e.printStackTrace();
} } }
com.pb.demo6.MyException: 性别只能是男或者女
Java从零开始学十九(异常)的更多相关文章
- Java从零开始学十四(包和访问控制)
一.java中的包 Java文件的组织形式Windows中的文件功能类似 在开发比较大的项目时,不可能只涉及到一个java文件,可能要创建几十,甚至几百个java文件,这个时候,我们就可以使用包,把相 ...
- Java从零开始学十八(抽象类和接口)
一.什么是抽象类和接口 抽象类.接口与类是一个层次的概念,是java中极其重要的概念. 抽象类是从多个类中抽象出来的公共模板,提供子类均具有的功能. 接口是从多个类中抽象出来的规范,体现的是规范和实现 ...
- Java从零开始学十六(多态)
一.什么是多态 多态性是指允许不同类的对象对同一消息作出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活.抽象.行为共享.代码共享的优势,很好的解决了应用程序函数同名问题.多态有两种表现形 ...
- Java从零开始学十五(继承)
一.继承作用 继承使用复用以前的代码非常容易,能够大大的缩短开发周期,降低开发成本,同时增加程序的易维护性 继承使重一个类A能够直接使用另外一个类B的属性和方法的一种途径 类A可以有自己的属性和方法 ...
- Java从零开始学十(Arrays类对数组的常用方法)
一.Arrays类常用方法 二.简单例子 package com.pb.demo1; import java.util.Arrays; /* * Arrays工具类的中的几个常用方法 * 1.copy ...
- Java从零开始学十二(构造方法)
一.构造方法 构造方法的主要目的是为类中的属性初始化 二.构造方法的定义格式 class 类名称{ 访问权限 类名称(类型1 参数1,类型2 参数2,…){ 程序语句 ; … // 构造方法没有 ...
- Java IO(十九)PrintStream 和 PrintWriter
Java IO(十九)PrintStream 和 PrintWriter 一.介绍 (一).PrintStream PrintStream 是打印输出流,它继承于FilterOutputStream. ...
- Java进阶(三十九)Java集合类的排序,查找,替换操作
Java进阶(三十九)Java集合类的排序,查找,替换操作 前言 在Java方向校招过程中,经常会遇到将输入转换为数组的情况,而我们通常使用ArrayList来表示动态数组.获取到ArrayList对 ...
- “全栈2019”Java多线程第二十九章:可重入锁与不可重入锁详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
随机推荐
- CF 277.5 A.SwapSort 水题
//STL教你做人系列 #include<stdio.h> #include<iostream> #include<math.h> #include<algo ...
- MultCloud – 支持数据互传的网盘管理
MultCloud https://www.multcloud.com/ 是一款在线服务,可以在一个地方管理众多网盘,支持国产百度盘, 最具有特色的地方是你可以直接在 MultCloud 里操作将 D ...
- 《TD式创新”祸国殃民》
TD式创新”祸国殃民> 作者:北京邮电大学 阚凯力 (2014年12月16日) 电信业内早就众所周知的TD-SCDMA真相,终于公之于天下.铁的事实是,它从来就不是什么“自主知识产权”,而是西门 ...
- MVC批量更新,可验证并解决集合元素不连续控制器接收不完全的问题
在"MVC批量添加,增加一条记录的同时添加N条集合属性所对应的个体"中,有2个问题待解决: 1.由jquery动态生成了表单元素,但不能实施验证. 2.一旦集合元素不连续,控制器就 ...
- failed to get the task for process XXX(解决方案)
引人: iOS真机调试程序,报如下错误信息: failed to get the task for process XXX 原因: 证书问题,project和targets的证书都必须是开发证书,AD ...
- 【linux】linux查看文件大小,磁盘大小
查看指定目录下 文件或目录大小超过多少的 查看 /backup/tomcat7/ 目录下 超过500M大小的文件 并展示 文件详情 find /backup/tomcat7/ -type f -si ...
- 2012年及之后的ImageNet比赛的冠军、亚军和季军ImageNet winners after 2012
2012 0.15 - Supervision (AlexNet) - ~ 60954656 params 0.26 - ISI (ensemble of features) 0.27 - LEAR ...
- vim/vi 命令详解
在工作中,要对服务器上的文件进行的修改,可以使用ssh远程登录到服务器上,并且使用vi进行快速的编辑即可,在没有图形界面的环境下,要编辑文件,vi是最佳选择! vi命令是Linux中最经典的文本编辑器 ...
- 数学图形之SineSurface与粽子曲面
SineSurface直译为正弦曲面.这有可能和你想象的正弦曲线不一样.如果把正弦曲线绕Y轴旋转,得到的该是正弦波曲面.这个曲面与上一节中的罗马曲面有些相似,那个是被捏过的正四面体,这个则是个被捏过正 ...
- C# 实现PNG文件的背景透明显示,解决动态显示闪烁问题 【转】
http://blog.sina.com.cn/s/blog_402c071e0102x4rl.html 以下内容,对于想要使用C#实现PNG图片背景透明显示,同时动态显示时无闪烁问题的人来说, ...