1.异常的概念

package cn.jxufe.java.chapter08.demo01;

public class Test01ArithmeticException {

    public static void main(String[] args) {
// TODO Auto-generated method stub
division(30, 3);
division(30, 0);
} public static void division(int a, int b) {
System.out.println("计算除法");
System.out.println("结果。。。" + a / b);
}
}

2.异常类

3.异常和错误的区别

异常:指程序在编译、运行期间发生了某种异常(XxxException),我们可以对异常进行具体的处理。若不处理异常,程序将会结束运行。

错误:指程序在运行期间发生了某种错误(XxxError),Error错误通常没有具体的处理方式,程序将会结束运行。Error错误的发生往往都是系统级别的问题,都是jvm所在系统发生的,并反馈给jvm的。我们无法针对处理,只能修正代码。

package cn.jxufe.java.chapter08.demo01;

public class Test02ExceptionAndError {

    /*
* Throwable
* Exception 异常 感冒,阑尾炎
* 将异常处理掉,可以继续执行
* RuntimeException
* Error 非典,艾滋,癌
* 必须修改程序
*/
public static void main(String[] args) {
int[] arr = new int[999999999];//错误,没有那么大的堆内存
System.out.println(arr[3]); } }

4.异常对象的产生和处理流程

5.抛出异常throw和throws

在编写程序时,我们必须要考虑程序出现问题的情况。比如,在定义方法时,方法需要接受参数。那么,当调用方法使用接受到的参数时,首先需要先对参数数据进行合法的判断,数据若不合法,就应该告诉调用者,传递合法的数据进来。这时需要使用抛出异常的方式来告诉调用者。

在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象。那么,抛出一个异常具体如何操作呢?

  • 1,创建一个异常对象。封装一些提示信息(信息可以自己编写)。
  • 2,需要将这个异常对象告知给调用者。怎么告知呢?怎么将这个异常对象传递到调用者处呢?通过关键字throw就可以完成。throw 异常对象;

throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。

使用格式:

throw new 异常类名(参数);

例如:
throw new NullPointerException("要访问的arr数组不存在");
throw new ArrayIndexOutOfBoundsException("该索引在数组中不存在,已超出范围");

声明:将问题标识出来,报告给调用者。如果方法内通过throw抛出了编译时异常,而没有捕获处理(稍后讲解该方式),那么必须通过throws进行声明,让调用者去处理。

声明异常格式:

修饰符 返回值类型 方法名(参数) throws 异常类名1,异常类名2… {   }

package cn.jxufe.java.chapter08.demo01;

public class Test03Throw {

    public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
int[] arr = {};
int temp = getArray(arr);
} public static int getArray(int[] arr) throws Exception {
// 对方法参数进行合法性的判断,进行判断是不是null
if (arr == null) {
// 抛出异常的形式,告诉调用者
// 关键字 throw
throw new Exception("数组不存在");
}
// 对数组进行判断,判断数组中,是不是有元素
if (arr.length == 0) {
// 抛出异常的形式,告诉调用者,数组没有元素
throw new Exception("数组中没有元素");
}
int i = arr[arr.length - 1];
return 2 * i;
}
}

6.try-catch-finally捕获异常

捕获异常格式:
try {
//需要被检测的语句。
}
catch(异常类 变量) { //参数。
//异常的处理语句。
}
finally {
//一定会被执行的语句。
}

try:该代码块中编写可能产生异常的代码。

catch:用来进行某种异常的捕获,实现对捕获到的异常进行处理。

finally有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行不到。而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会被执行的。

package cn.jxufe.java.chapter08.demo01;

public class Test04TryCatchFinally {

    public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = null;
try {
int i = getArray(arr);
System.out.println(i); } catch (NullPointerException ex) {
System.out.println("###" + ex); } catch (ArrayIndexOutOfBoundsException ex) { System.out.println("!!!!!!" + ex);
}
System.out.println("Game Over");
} /*
* 定义方法,抛出异常
* 调用者使用try catch
*/
public static int getArray(int[] arr) throws NullPointerException, ArrayIndexOutOfBoundsException {
// 对数组判空
if (arr == null) {
// 手动抛出异常,抛出空指针异常
throw new NullPointerException("数组不存在");
}
// 对数组的索引进行判断
if (arr.length < 3) {
// 手动抛出异常,抛出数组的索引越界异常
throw new ArrayIndexOutOfBoundsException("数组没有3索引");
}
return arr[3] + 1;
}
}

7.多个异常处理的细节

package cn.jxufe.java.chapter08.demo01;

/*
* 多catch写在一起
* 细节:
* catch小括号中,写的是异常类的类名
* 有没有顺序的概念,有
*
* 平级异常: 抛出的异常类之间,没有继承关系,没有顺序
* NullPointerException extends RuntimeException
* NoSuchElementException extends RuntimeException
* ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException extends RuntimeException
*
* 上下级关系的异常
* NullPointerException extends RuntimeException extends Exception
* 越高级的父类,写在下面
*/
public class Test05Catch { public static void main(String[] args) {
// TODO Auto-generated method stub
try { } catch (NullPointerException ex) { } catch (Exception ex) { }
} public static void function(int a) throws NullPointerException, Exception {
if (a == 0) {
throw new NullPointerException();
}
if (a == 1) {
throw new Exception();
}
}
}

8.运行异常

package cn.jxufe.java.chapter08.demo01;

import java.util.Scanner;
/*
* 异常分为编译异常和运行时期异常
* 编译异常: 调用了抛出异常的方法,不处理编译失败 (try throws)
* 运行异常: 抛出的异常是RuntimeException类,或者是他的子类
*
* 运行异常的特点:
* 方法内部抛出的异常是运行异常, new XXXException
* 方法的声明上,不需要throws语句,调用者,不需要处理
* 设计原因:
* 运行异常,不能发生,但是如果发生了,程序人员停止程序修改源代码
*
* 运行异常: 一旦发生,不要处理,请你修改源代码, 运行异常一旦发生,后面的代码没有执行的意义
*/
public class Test06QuotientWtihException { public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
System.out.println("enter two integers: ");
int number1 = input.nextInt();
int number2 = input.nextInt();
try {
int result = quotient(number1, number2);
System.out.println(number1 + " / " + number2 + " is " + result); } catch (ArithmeticException e) {
// TODO: handle exception
System.out.println(e+"不能除以0");
}
} public static int quotient(int number1, int number2) {//不用声明异常
if (number2 == 0)
throw new ArithmeticException("Divisor cannot be zero");//ctrl+T查看继承关系:运行异常,不用声明异常
return number1 / number2;
}
}

 运行异常的案例

package cn.jxufe.java.chapter08.demo01;

public class Test07RuntimeException {

    public static void main(String[] args)  {
// TODO Auto-generated method stub
double d = 0;
try {
d = getArea(-1);
} catch (Exception e) {
// TODO Auto-generated catch block
}
System.out.println(d);
}
/*
* 定义方法,计算圆形的面积
* 传递参数0,或者负数,计算的时候没有问题
* 但是,违反了真实情况
* 参数小于=0, 停止程序,不要在计算了
*/
public static double getArea(double r) throws Exception{
if(r <= 0)
throw new Exception("圆形不存在");
return r*r*Math.PI;
}
}

这个例子说明,有些参数有问题,导致后面的程序无法计算了,那么就应该用RuntimeException。

package cn.jxufe.java.chapter08.demo01;

public class Test07RuntimeException {

    public static void main(String[] args) {
// TODO Auto-generated method stub
double d = getArea(-1);
System.out.println(d);
} /*
* 定义方法,计算圆形的面积
* 传递参数0,或者负数,计算的时候没有问题
* 但是,违反了真实情况
* 参数小于=0, 停止程序,不要在计算了
*/
public static double getArea(double r) {
if (r <= 0)
throw new RuntimeException("圆形不存在");
return r * r * Math.PI;
}
}

9.使用异常的好处

package cn.jxufe.java.chapter08.demo01;

import java.util.InputMismatchException;
import java.util.Scanner; public class Test08MismatchException { public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
boolean continueInput = true;
System.out.println("enter an integer:");
do {
try {
int number = input.nextInt();
System.out.println("the number entered is " + number);
continueInput = false; } catch (InputMismatchException e) {
// TODO: handle exception
System.out.println("try again : an integer is required ");
input.nextLine(); //输入不合法可以连续输入
}
} while (continueInput);
System.out.println("输入完成。。。");
}
}

10.从异常中获取信息

package cn.jxufe.java.chapter08.demo01;

import com.sun.management.jmx.Trace;

public class Test09Exception {

    public static void main(String[] args) {
// TODO Auto-generated method stub
try {
System.out.print(sum(new int[] {1,2,3,4,5}));
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
System.out.println("\n"+ e.getMessage());
System.out.println("\n" + e.toString()); System.out.println("\nTrace Info Obtained from getStackTrace");
StackTraceElement[] stackTraceElements = e.getStackTrace();
for (int i = 0; i < stackTraceElements.length; i++) {
System.out.println("method " + stackTraceElements[i].getMethodName());
System.out.println("(" + stackTraceElements[i].getClassName()+":");
System.out.println(stackTraceElements[i].getLineNumber()+")"); }
}
} public static int sum(int[] list) {
int result = 0;
for (int i = 0; i <= list.length; i++) { //有一个<=的异常
result += list[i];
}
return result;
}
}

11.异常在方法重写中的细节

  • 子类覆盖父类方法时,如果父类的方法声明异常,子类只能声明父类异常或者该异常的子类,或者不声明。
例如:
class Fu {
public void method () throws RuntimeException {
}
}
class Zi extends Fu {
public void method() throws RuntimeException { } //抛出父类一样的异常
//public void method() throws NullPointerException{ } //抛出父类子异常
}
  • 当父类方法声明多个异常时,子类覆盖时只能声明多个异常的子集。
例如:
class Fu {
public void method () throws NullPointerException, ClassCastException{
}
}
class Zi extends Fu {
public void method()throws NullPointerException, ClassCastException { } public void method() throws NullPointerException{ } //抛出父类异常中的一部分
public void method() throws ClassCastException { } //抛出父类异常中的一部分
}
  • 当被覆盖的方法没有异常声明时,子类覆盖时无法声明异常的。
例如:
class Fu {
public void method (){
}
}
class Zi extends Fu {
public void method() throws Exception { }//错误的方式
}

举例:父类中会存在下列这种情况,接口也有这种情况

问题:接口中没有声明异常,而实现的子类覆盖方法时发生了异常,怎么办?

答:无法进行throws声明,只能catch的捕获。万一问题处理不了呢?catch中继续throw抛出,但是只能将异常转换成RuntimeException子类抛出。

interface Inter {
public abstract void method();
}
class Zi implements Inter {
public void method(){ //无法声明 throws Exception
int[] arr = null;
if (arr == null) {
//只能捕获处理
try{
throw new Exception(“哥们,你定义的数组arr是空的!”);
} catch(Exception e){
System.out.println(“父方法中没有异常抛出,子类中不能抛出Exception异常”);
//我们把异常对象e,采用RuntimeException异常方式抛出
throw new RuntimeException(e);
}
}
}
}

12.自定义异常

通过阅读异常源代码:发现java中所有的异常类,都是继承Throwable,或者继承Throwable的子类。这样该异常才可以被throw抛出。

说明这个异常体系具备一个特有的特性:可抛性:即可以被throw关键字操作。

并且查阅异常子类源码,发现每个异常中都调用了父类的构造方法,把异常描述信息传递给了父类,让父类帮我们进行异常信息的封装。

例如NullPointerException异常类源代码:
public class NullPointerException extends RuntimeException {
public NullPointerException() {
super();//调用父类构造方法
}
public NullPointerException(String s) {
super(s);//调用父类具有异常信息的构造方法
}
}
package cn.jxufe.java.chapter08.demo01;

public class Test10OurClassException {

    public static void main(String[] args) {
// TODO Auto-generated method stub
int avg = getAvg(50, 60, -70, 80);
System.out.println(avg);
} /*
* 传递成绩,计算成绩的平均数
* 成绩没有负数,需要抛出异常,停止运算
*/
public static int getAvg(int... source) {
int sum = 0;
for (int s : source) {
if (s < 0) {
throw new FuShuException("成绩错误 " + s);
}
sum = sum + s;
}
return sum / source.length;
}
} /*
* 自定义异常
* 继承Exception,或者继承RuntimeException
* 构造方法中,super将异常信息,传递给父类
*/
class FuShuException extends RuntimeException {
public FuShuException(String s) {
super(s);
} public FuShuException() {
}
}

08java进阶——异常的更多相关文章

  1. [Java 进阶]异常

    异常:程序在运行过程中发生由于硬件设备问题.软件设计错误等导致的程序异常事件. 世上没有百分之百完美的程序.程序总难免存在各式各样的问题.所以,程序中添加对于错误的处理机制是十分有必要的.这就好比人多 ...

  2. struts2 进阶--异常捕获机制

    在SpringMvc中有自己的异常处理机制,struts2当然会有此功能,主要是在struts.xml中配置: <bean type="com.opensymphony.xwork2. ...

  3. Java编程——学习大纲

    Java基础 Java基础--JDK的安装和配置 Java基础--Eclipse使用 Java基础--基本概念.数据类型.运算符 Java扩展--整型和浮点型在计算机中的存储格式 Java基础--流程 ...

  4. 3.Java异常进阶

    3.JAVA异常进阶 1.Run函数中抛出的异常 1.run函数不会抛出异常 2.run函数的异常会交给UncaughtExceptionhandler处理 3.默认的UncaughtExceptio ...

  5. spring boot / cloud (十二) 异常统一处理进阶

    spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...

  6. python 异常之进阶操作

    1.文件分析 下面来做一些文件分析操作,分析整本书的信息. 知识点: string.split():将字符串分解为列表. open(filename,‘rb’)或者open(filename,enco ...

  7. Java基础进阶:时间类要点摘要,时间Date类实现格式化与解析源码实现详解,LocalDateTime时间类格式化与解析源码实现详解,Period,Duration获取时间间隔与源码实现,程序异常解析与处理方式

    要点摘要 课堂笔记 日期相关 JDK7 日期类-Date 概述 表示一个时间点对象,这个时间点是以1970年1月1日为参考点; 作用 可以通过该类的对象,表示一个时间,并面向对象操作时间; 构造方法 ...

  8. 窗体Showmedol 遇到的奇怪异常-->进阶问题

    procedure SetTransparentForm (popupFrm:TForm;Color:TColor;AlphaBlendValue:Integer); var FrmTranspare ...

  9. 【javascript进阶】异常

    前言 最近有些时间了,今天看了看博客的后台记录,好多都没有写博客呢,争取尽快把以前的补上,javascrit中的异常在前端大家用的好像不是很多,其实javascript的异常和大多数的后端语言差不大, ...

随机推荐

  1. vscode-php代码提升及函数跳转

    安装插件,php intellisense 安装后还要配置一下PHP的运行路径 打开扩展     输入 PHP IntelliSense     安装     文件 - 首选项 - 设置 - 扩展 - ...

  2. hibernate多对一单项关联映射

    1.实体类编写: 用户类: public class User { private int id; private String name; private Group group; ..... } ...

  3. (转)搭建自己的Nuget服务器

    转:https://www.cnblogs.com/knowledgesea/p/5500954.html 序言 你们公司有没有好多项目,有没有好多类库,你们的类库是在tfs中管理,还是svn或者gi ...

  4. tp5 select

    tp5  select出来的数据 和tp3.2select出来的数据 不一样, tp5  select出来的数据  含有很多我们不需要的东西,让我们小菜鸟看的很痛苦 解决办法 $date是查询出来的结 ...

  5. centos7 升级php版本

    centos7 默认PHP5.4,版本太低,很多要求至少PHP5.5 1.查看已经安装的PHP组件 yum list installed| grep php php.x86_64 -.el7 @bas ...

  6. iOS SDK开发之 .a静态库

    查看.framework静态库的生成及使用单击此处 注:这篇教程将只使用一小部分Objective-C代码,本文主要讲解从开始到应用的详细步骤.环境:xcode 9.2下面我们开始操作: 第一步:创建 ...

  7. 中国MOOC_零基础学Java语言_第7周 函数_1分解质因数

    第7周编程题 查看帮助 返回   第7周编程题 依照学术诚信条款,我保证此作业是本人独立完成的. 温馨提示: 1.本次作业属于Online Judge题目,提交后由系统即时判分. 2.学生可以在作业截 ...

  8. Matlab——表达式 阵列与矩阵的创建

    表达式 指令过长: 如果一个指令过长可以在结尾加上... 下一行继续写指令即可 若不想每次都显示运算结果,只需在运算式最後加上分号(:)即可 注释 基本的算术运算有: 加 (+).减 (-).乘 (* ...

  9. 关于WordPress中字体加载慢的问题解决方案(转)

    2016-04-15 最近发现Wordpress有时候加载的特别慢,于是就想办法找了下原因.之前听网上说是因为wordpress用的是Google的字体库,而且是每次都要加载,导致访问慢的,于是当时装 ...

  10. tensorflow学习之Saver保存读取

    目前不是很懂..但主要意思是tf可以把一开始定义的参数,包括Weights和Biases保存到本地,然后再定义一个变量框架去加载(restore)这个参数,作为变量本身的参数进行后续的训练,具体如下: ...