java基础第10天
Java异常 Exception
异常指的的在运行期出现的错误,在编译阶段出现的语法错误等,不能称之为异常。
编译类异常
必须处理之后才能正常编译(类找不到,IO异常,在API文档中明确写明throws的方法,必须要进行处理)
运行时异常(RuntimeException)
这种异常可以处理也可以不处理。
运行时异常的解决方法
遇到错误终止程序的运行,即不对异常进行处理
由程序员在编写程序的时,就考虑到错误的检测、错误的消息的提示,在抛给Java运行环境的时候,就将这个异常对象捕获,在进行处理。
使用try/catch语句捕获异常对象
public class Exception1 {
public static void main(String[] args){
int[] arr = {1,2,3};
try{
System.out.println(arr[4]); //加上try语块
}catch(Exception e){
System.out.println("发生数组越界");
}
}
}
try尝试:将可能发生异常的语句放入其中
catch捕获:当try块中的异常发生时,将产生一个异常对象,拿着这个对象去匹配catch块中的异常类,如果和catch中的类型匹配了,就执行这个catch块中的语句,这就是意味着,catch块可以有多个。
public class Exception2 {
public static void main(String[] args){
String str =null;
try{
System.out.println(str.length());
}catch(NullPointerException e){
System.out.println("空指针");
}catch(Exception e){
System.out.println("未知错误");
}
}
}
从程序上可以看出,一个try后可以加多个catch块,针对try语句块中发生的异常分别捕获,当然,只能有一个catch块碑执行,从执行的逻辑上看,和switch分支语句很相似。
进行异常捕获时,所有父类异常块都应该排在子类异常catch块的后面
访问异常信息
程序需要在catch块中访问异常对象的相关信息,可以通过访问catch块后的异常形参来获得,当Java运行时决定调用某个catch块来处理该异常对象时,会将异常对象赋值给catch块后的异常参数(即:异常类型的形参),程序即可通过该参数来获得异常的相关信息。
getMessage():返回该异常的详细描述信息
printStackTracwe():将异常的跟踪栈信息打印出来
printStackTrace(PrintStream s):将异常的跟踪栈信息输出到指定的输出流
getStackTrace():返回该异常的跟踪栈信息
import java.io.FileInputStream; //导包
public class Exception3 {
public static void main(String[] args){
try{
FileInputStream fis = new FileInputStream("aa");
}catch(Exception e){
System.out.println(e.getMessage()); //打印异常信息
e.printStackTrace(); //打印跟踪信息
}
}
}
编译时异常(必须捕获)
import java.io.FileInputStream;
public class Exception4 {
public static void main(String[] args){
FileInputStream in = null;
try{
in = new FileInputStream("aa");
}catch(Exception e){
e.printStackTrace();
}
}
}
finally回收资源
完整的异常处理结构
try{
业务处理语句
}catch(异常1 e1){
异常处理语句
}catch(异常2 e2){
异常处理语句
}
...
finally{
资源回收语句
}
注意:
在异常处理的机构中,只有try块是必须的,也就是说,如果没有try块,则不能有后面的catch和finally块,catch与finally二者中至少出现一个,当然也可以同时出现;finally位于所有catch块的后面
import java.io.FileInputStream;
import java.io.IOException;
public class Exception5 {
public static void main(String[] args){
FileInputStream fis = null;
try{
fis = new FileInputStream("aa");
}catch(IOException i){
System.out.println("发生异常");
}finally{
System.out.println("总会执行");
}
}
}
注意:System.exit(1);退出虚拟机 ####总结 - 除非在try块,catch块中调用了退出虚拟机的方法,否则不管在try块,catch块中执行怎样的代码,出现怎样的情况,finally块中的语句总会被执行。 - 通常情况下,不要在finally块中使用return或者throw等导致方法终止的语句,一旦在finally块中使用了return或者throw语句,将会导致try块,catch块中的return,throw语句失效。
public class Exception6 {
public static void main(String[] args){
int res = test();
System.out.println(res); // 打印结果为3
}
public static int test(){
try{
System.out.println(2/0);
return 1;
}catch(Exception e){
return 2;
}finally{
return 3;
}
}
}
Checked异常和Runtime异常体系
Checked异常:编译时异常
Runtime异常:运行时异常
对于Checked异常有两种处理方式:
当前方法明确知道该如何处理该异常,程序应该使用try/catch块来捕获该异常,然后在对应的catch块中进行修复异常
当前方法不知道如何处理该异常,应在方法声明时抛出该异常
Runtime异常处理方式:
Runtime异常无需明显式抛出,如果储蓄需要捕获Runtime异常,也可以使用try/catch块来实现。
使用throws声明抛出异常,是对异常的一种处理方式
当前方法不知道如何处理这种类型的异常,该异常应该由上一级的调用者处理;如果main方法也不知道如何处理这种类型的异常,也可以使用throws继续声明抛出,将该异常交给JVM处理。JVM对异常的处理方法是打印异常的跟踪栈信息,并终止程序运行。
throws声明抛出异常的语法格式
方法签名+ throws Exception1,Exception2...
一旦一个方法使用throws关键字声明抛出了该异常,程序就无需使用try/catch块来捕获该异常了
import java.io.*;
public class Exception8 {
public static void main(String[] args) throws Exception{ //继续将异常抛出,交由JVM处理
test();
}
public static void test() throws Exception{ //抛出异常
FileInputStream fis = new FileInputStream("aa");
}
}
在定义一个方法时,使用throws声明抛出异常有一个限制
方法重写时,子类方法声明抛出的异常类型应该是父类声明抛出的异常类型的子类或者相同,子类声明抛出的异常不允许比父类方法声明抛出的异常大
总结
使用checked异常有如下不方便的地方
对于checked异常,必须显示的捕获并处理该异常,或者显式的声明抛出该异常,这样无疑增加了编程的复杂度
如果方法中显式抛出checked异常将会导致方法签名与异常耦合在一起,如果该方法时重写父类的方法,则该方法抛出的异常还会受到被重写方法所抛出异常的限制
如何自行抛出异常
在程序中抛出异常的话,需要使用到throw语句
首先要生成异常类对象,其语法格式如下:
IOException e = new IOException();
throw e;
对于Checked异常与Runtime异常的处理方法
如果throw语句抛出的异常为Checked异常,则该throw语句要么处于try块里显式捕获该异常,要么放在一个带throws声明抛出的方法中,即把该异常交给方法的调用者去处理;
如果throw语句抛出的是Runtime异常,则该语句无须放在try块中,也无须放在带throws声明的方法;
import java.io.IOException;
public class Exception9 {
public static void main(String[] args){
//被调用的checkedEx方法会抛出异常,并且是编译异常,必须用try,catch捕获,或者是在调用的方法上继续声明抛出
try{
checkedEx();
}catch(Exception e){
e.printStackTrace();
}
//被调用的方法会抛出运行时异常,可以完全不理会,由调用者处理,这里的调用者就是main方法
runtimeEx();
}
//方法中抛出的异常是编译异常,必须要进行处理:要么放在try块中,要么在方法声明上加上抛出声明
public static void checkedEx() throws IOException{
throw new IOException("checked Exception");
}
public static void runtimeEx(){
//方法中抛出的异常是运行时异常,可以处理,也可以不理会
throw new NullPointerException();
}
}
方法抛出异常的流程图,以(IOException--编译异常)为例
自定义异常类
定义异常类时通常需要提供两个构造方法,一个是无参的,一个是带有一个字符串的构造方法,这个字符串将作为该异常对象的描述信息,也就是对异常对象的getMessage方法的返回值
自定义一个异常类的语法如下
public class MyException extends Exception{
public MyException(){} //空参构造
public MyException(String s){// 有参构造 字符串作为信息传递
super(s); //调用父类Exception的构造方法
}
}
案例练习
/*
编写应用程序EcmDef.java,接收命令行的两个参数,要求不能输入负数,计算两数相除。
对数据类型不一致(NumberFormatException)
缺少命令行参数(ArrayIndexOutOfBoundsException
除0(ArithmeticException)
及输入负数(EcDef 自定义的异常)进行异常处理。
前几种异常,Java中都已经有相应的异常类了,但是最后一种对输入负数的异常,系统没有这样的异常定义,所以,这个异常应该是我们自定义的异常。
提示:
(1)在主类(EcmDef)中定义异常方法(ecm)完成两数相除功能。
(2)在main()方法中使用异常处理语句进行异常处理。
(3)在程序中,自定义对应输入负数的异常类(EcDef)。
(4)运行时接受参数 java EcmDef 20 10
//args[0]=“20” args[1]=“10”
(5)Interger类的static方法parseInt(String s)将s转换成对应的int值。
如int a=Interger.parseInt(“314”); //a=314;
复习如何使用API文档,查看Integer类的方法
*/
public class Exception11 {
public static void main(String[] args){
try{
int a = Integer.parseInt(args[1]);
int b = Integer.parseInt(args[2]);
int res = dev(a,b);
System.out.println(res);
}catch(NumberFormatException nfe){
System.out.println("数据类型不一致");
}catch(ArrayIndexOutOfBoundsException a){
System.out.println("缺少命令行参数");
}catch(ArithmeticException ae){
System.out.println("除数不能为0");
}catch(MyException me){
System.out.println(me.getMessage());
}
}
public static int dev(int a,int b) throws MyException{
if(a<0||b<0){
throw new MyException("除数不能为负数");
}
return a/b;
}
}
//自定义异常类
class MyException extends Exception{
public MyException(){}
public MyException(String s){
super(s);
}
}
java基础第10天的更多相关文章
- JAVA基础(10)——IO、NIO
转载:http://blog.csdn.net/weitry/article/details/52964948 JAVA基础系列规划: JAVA基础(1)——基本概念 JAVA基础(2)——数据类型 ...
- 夯实Java基础系列10:深入理解Java中的异常体系
目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...
- Java基础语法(10)-面向对象之三大特征
title: Java基础语法(9)-面向对象之类的成员 blog: CSDN data: Java学习路线及视频 1.面向对象特征--封装 为什么需要封装?封装的作用和含义? 我要用洗衣机,只需要按 ...
- Java 基础【10】 I/O流概念分析整理
转载地址:http://blog.csdn.net/yuebinghaoyuan/article/details/7388059 java.io 中的流,可以从不同的角度进行分类. 按照数据流的方向不 ...
- Java基础教程(10)--类
一.声明类 你已经见过了以如下方式定义的类: class MyClass { // field, constructor, and method declarations } 上面是声明类的最 ...
- Java基础(10)——小结与填坑
前面都写了9篇啦,虽然断断续续发了半个月,写着写着会发现每篇中都有些比较重要的地方没有讲到~这篇还是需要填一填目前我已发现的坑了~ 一. 小结 Java编译命令 javac.运行命令java java ...
- java基础练习 10
import java.util.Scanner; public class Tenth { /*有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数*/ public stati ...
- 【Java基础】10、Java中throw和throws的区别
系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 ...
- JAVA基础--异常10
一.Object类简介 1.Object类简介 Object,是Java一切对象的最高父类:如果一个类没有显示继承一个类,他的父类就是Object: 它描述的是Java世界里所有对象最最共性的信息,它 ...
随机推荐
- appfog 添加数据库支持
1.PhpMyAdmin与app 在同一应用 1.cd进入应用所在的文件夹,输入 git clone git://github.com/appfog/af-php-myadmin.git 2.进入本地 ...
- 一个Spark job的生命历程
一个job的生命历程 dagScheduler.runJob //(1) --> submitJob ( eventProcessLoop.post(JobSubmitted,***) //(2 ...
- Linux安装rpm包时报错Header V3 DSA/SHA1 Signature, key ID 1d1e034b: NOKEY解决办法
这是因为yum安装了旧版本的GPG key造成的,解决办法: rpm --import /etc/pki/rpm-gpg/RPM* Header V3 DSA/SHA1 Signature, key ...
- mydumper/myloader使用详解
mydumper安装:http://www.cnblogs.com/lizhi221/p/7010174.html mydumper原理:http://www.cnblogs.com/lizhi2 ...
- ELK日志分析工具
一.ELK介绍 1.1 elasticsearch 1.1.1 elasticsearch介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎 ...
- 多口USB HUB信号延长器 USBX-M200(针对于A客户使用时很棒吧)
大家都知道A客户是不允许在设备里面出现无线的东东,但是USB的传输距离有很短.咋办呢?? 见下图 http://rextron-cn.com/product_show.asp?id=74
- 如何用 testNG 生成测试报告
原文地址https://testerhome.com/topics/3473 总结一下testNG生成报告的三种方式,基本都是我直接转载的,没有补充就不说了,有补充的我会加以说明的(这里直说生成报告, ...
- CSS控制列表样式属性list-style有哪些?怎么用?
CSS列表样式属性list-style有哪些类型?不同类型CSS控制列表样式使用时该注意什么? 这是W3Cschool用户Shirley于2016-11-10在W3Cschool编程问答提出的问题.云 ...
- java之进程和线程
1.进程和线程的通俗例子. 2.进程和线程关系.
- hdu5057 分块处理,当数值大于数据范围时树状数组 真是巧 将大数据分为小数据来处理
这题说的给了100000个数有100000次操作 询问 L和R 区间内 在D位上为P的个数,用树状数组存 要开[10][10][100000]的int 开不了但是能开 这么大的unsign short ...