08java进阶——异常
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进阶——异常的更多相关文章
- [Java 进阶]异常
异常:程序在运行过程中发生由于硬件设备问题.软件设计错误等导致的程序异常事件. 世上没有百分之百完美的程序.程序总难免存在各式各样的问题.所以,程序中添加对于错误的处理机制是十分有必要的.这就好比人多 ...
- struts2 进阶--异常捕获机制
在SpringMvc中有自己的异常处理机制,struts2当然会有此功能,主要是在struts.xml中配置: <bean type="com.opensymphony.xwork2. ...
- Java编程——学习大纲
Java基础 Java基础--JDK的安装和配置 Java基础--Eclipse使用 Java基础--基本概念.数据类型.运算符 Java扩展--整型和浮点型在计算机中的存储格式 Java基础--流程 ...
- 3.Java异常进阶
3.JAVA异常进阶 1.Run函数中抛出的异常 1.run函数不会抛出异常 2.run函数的异常会交给UncaughtExceptionhandler处理 3.默认的UncaughtExceptio ...
- spring boot / cloud (十二) 异常统一处理进阶
spring boot / cloud (十二) 异常统一处理进阶 前言 在spring boot / cloud (二) 规范响应格式以及统一异常处理这篇博客中已经提到了使用@ExceptionHa ...
- python 异常之进阶操作
1.文件分析 下面来做一些文件分析操作,分析整本书的信息. 知识点: string.split():将字符串分解为列表. open(filename,‘rb’)或者open(filename,enco ...
- Java基础进阶:时间类要点摘要,时间Date类实现格式化与解析源码实现详解,LocalDateTime时间类格式化与解析源码实现详解,Period,Duration获取时间间隔与源码实现,程序异常解析与处理方式
要点摘要 课堂笔记 日期相关 JDK7 日期类-Date 概述 表示一个时间点对象,这个时间点是以1970年1月1日为参考点; 作用 可以通过该类的对象,表示一个时间,并面向对象操作时间; 构造方法 ...
- 窗体Showmedol 遇到的奇怪异常-->进阶问题
procedure SetTransparentForm (popupFrm:TForm;Color:TColor;AlphaBlendValue:Integer); var FrmTranspare ...
- 【javascript进阶】异常
前言 最近有些时间了,今天看了看博客的后台记录,好多都没有写博客呢,争取尽快把以前的补上,javascrit中的异常在前端大家用的好像不是很多,其实javascript的异常和大多数的后端语言差不大, ...
随机推荐
- @清晰掉 C++ 中的 enum 结构在内存中是怎么存储的?
C++ 中的 enum 结构在内存中是怎么存储的? C++ C++ 中的 enum 结构在内存中是怎么存储的?里面存储的是常量值吗? 关于占用内存的大小,enum类型本身是不占内存的,编译器直接 ...
- 电脑出现了一块tap window adapter v9 网卡 以及虚拟机桥接模式无法通信原因
计算机与外界局域网的连接是通过主机箱内插入一块网络接口板(或者是在笔记本电脑中插入一块PCMCIA卡).网络接口板又称为通信适配器或网络适配器(network adapter)或网络接口卡NIC(Ne ...
- 2、Shiro的认证
Shiro的认证流程大体可以参考下面这幅图: 但是没有接触过shiro的同学看到上面的图片也不明白,下面我们来在代码中尝试体验Shiro的认证过程: 1.新建一个SpringBoot项目项目结构如下: ...
- 2、electron进程
electron核心我们可以分成2个部分,主进程和渲染进程. 主进程: 主进程连接着操作系统和渲染进程,可以把她看做页面和计算机沟通的桥梁. Electron 运行 package.json 的 ma ...
- python - 简单化list的 For[if] 语句
python的list数据 >>>a=[, , , , , , ] >>>b=a >>>b [, , , , , , ] 用这种方式将a.list ...
- orm练习题
表关系图 models.py from django.db import models # Create your models here. class Teacher(models.Model): ...
- HAProxy & Keepalived L4-L7 高可用负载均衡解决方案
目录 文章目录 目录 HAProxy 负载均衡器 应用特性 性能优势 会话保持 健康检查 配置文件 负载均衡策略 ACL 规则 Web 监控平台 Keepalived 虚拟路由器 核心组件 VRRP ...
- DELPHI中函数、过程变量的声明与应用
Procedure型变量: 在DELPHI中,函数.过程的地址可以赋给一个特殊类型的变量,变量可用如下方式声明: var p : procedure(num:integer); //过程 或: var ...
- jeecg项目将workbook 的Excel流添加到zip压缩包里导出
1.直接献出代码 Map<String,List<ConfidentialInformation>> typeMap = new HashMap<>(); try ...
- 第十一周总结 继承、this和super的区别和用法、方法的重写和重载
一.继承 1.子类继承父类,通过一个关键字 extends 2.子类的对象可以调用父类中的(public protected)属性和方法 当作自己的来使用 3.子类可以添加自己独有的属性和方法 4.子 ...