Java 异常的处理方式--throws和try catch
异常的第一种处理方式throws。
看以下例子:
import java.io.*;
public class ExceptionTest04{
public static void main(String[] args){
m1();
}
public static void m1(){
m2();
}
public static void m2(){
m3();
}
public static void m3(){
new FileInputStream("c:/ab.txt"); //FileInputStream构造方法声明位置上使用throws(向上抛)
}
}
以上代码编译时出错:
ExceptionTest04.java:16: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
new FileInputStream("c:/ab.txt");
按照提示修改之后:
import java.io.*;
public class ExceptionTest04{
public static void main(String[] args){
m1();
System.out.println("hello");
}
public static void m1(){
m2();
}
public static void m2(){
m3();
}
public static void m3() throws FileNotFoundException{
new FileInputStream("c:/ab.txt");
}
}
编译时出错;
ExceptionTest04.java:30: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
m3();
由此看出,修改之后m3()运行时出现错误,上抛给m2(),以此类推,m2()上抛异常给m1(),m1()上抛异常给main()方法。
因此作出如下修改:
import java.io.*;
public class ExceptionTest04{
public static void main(String[] args) throws FileNotFoundException{
m1();
System.out.println("hello");
}
public static void m1() throws FileNotFoundException{
m2();
}
public static void m2() throws FileNotFoundException{
m3();
}
public static void m3() throws FileNotFoundException{
new FileInputStream("c:/ab.txt");
}
}
修改之后编译通过,但是System.out.println("hello")并不会执行。
从上面的例子中可以看出,使用throws处理异常不是真正处理异常而是推卸责任,谁调用就会抛给谁。上面的m1方法如果出现了异常,因为采用的是上抛,JVM遇到这个异常就会退出JVM,之后的代码不会执行。因此引入try...catch...方法。修改如下,编译运行通过,并且输出:hello。
import java.io.*;
public class ExceptionTest04{
public static void main(String[] args) throws FileNotFoundException{
try{
m1();
} catch(FileNotFoundException e){}
System.out.println("hello");
}
public static void m1() throws FileNotFoundException{
m2();
}
public static void m2() throws FileNotFoundException{
m3();
}
public static void m3() throws FileNotFoundException{
new FileInputStream("c:/ab.txt");
}
}
捕捉 try...catch...
先来看看语法,
try{
可能出现异常的代码;
}catch(异常类型1 变量){
处理异常的代码;
}catch(异常类型2 变量){
处理异常的代码;
}......
看以下例子:
import java.io.*;
public class ExceptionTest05{
public static void main(String[] args){
try{
//FileNotFoundException
FileInputStream fis=new FileInputStream("c:/ab.txt");
}catch(ArithmeticException e){ //捕获的异常是算术异常
}
}
}
以上的代码编译无法通过,因为FileNotFoundException没有处理,报错:
ExceptionTest05.java:19: 错误: 未报告的异常错误FileNotFoundException; 必须对其进行捕获或声明以便抛出
FileInputStream fis=new FileInputStream("c:/ab.txt");
^
1 个错误
也就是说可能出现异常的代码和捕获异常的代码必须是相对应的。
将捕获的异常修改之后,编译通过,
import java.io.*;
public class ExceptionTest05{
public static void main(String[] args){
try{
//FileNotFoundException
FileInputStream fis=new FileInputStream("c:/ab.txt");
}catch(FileNotFoundException e){
}
}
}
再看以下例子,以下程序编译无法通过,
import java.io.*;
public class ExceptionTest05{
public static void main(String[] args){
try{
//FileNotFoundException
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}catch(FileNotFoundException e){
}
}
}
报错:
ExceptionTest05.java:48: 错误: 未报告的异常错误IOException; 必须对其进行捕获或声明以便抛出
fis.read();
^
1 个错误
因为read()方法又抛出了IOException的异常,而catch()只处理了FileNotFoundException的异常。
read()方法的抛出的异常如下图所示:
要想编译通过,必选进行IOException处理,
import java.io.*;
public class ExceptionTest05{
public static void main(String[] args){
try{
//FileNotFoundException
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}catch(FileNotFoundException e){
}catch(IOException e){
}
}
}
或者如下直接进行IOException处理,这是因为FileNotFoundException继承IOException。
import java.io.*;
public class ExceptionTest05{
public static void main(String[] args){
try{
//FileNotFoundException
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}catch(IOException e){
}
}
}
再看以下例子:
import java.io.*;
public class ExceptionTest05{
public static void main(String[] args){
try{
//FileNotFoundException
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}catch(IOException e){
}catch(FileNotFoundException e){
}
}
}
编译出错:
ExceptionTest05.java:97: 错误: 已捕获到异常错误FileNotFoundException
}catch(FileNotFoundException e){
^
1 个错误
这是因为FileNotFoundException继承IOException,catch语句块虽然可以写多个,但是从上到下catch,必须从小类型异常到大类型异常进行捕捉。并且try...catch...中最多执行一个catch语句块,执行结束后,try...catch...就执行结束了。
最后看一个详细的例子总结一下之前的内容。
import java.io.*;
public class ExceptionTest06{
public static void main(String[] args){
FileInputStream fis=new FileInputStream("abc");
fis.read();
}
}
以上程序编译无法通过,可以进行如下处理,
import java.io.*;
public class ExceptionTest06{
public static void main(String[] args)throws IOException,FileNotFoundException{
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}
}
或者进行如下处理:
import java.io.*;
public class ExceptionTest06{
public static void main(String[] args)throws IOException{
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}
}
或者使用try...catch...进行异常处理。
import java.io.*;
public class ExceptionTest06{
public static void main(String[] args){
try{
FileInputStream fis=new FileInputStream("c:/ab.txt");
fis.read();
}catch(FileNotFoundException e){ //e内存地址指向的堆中的那个对象是FileNotFoundException类型的事件。
System.out.println("读取的文件不存在!");
}catch(IOException e){
System.out.println("其它IO异常!");
}
System.out.println("ABC");
}
}
运行之后输出:
读取的文件不存在!
ABC
如何取得异常对象的具体信息,常用的方法主要有两种:
取得异常信息描述:getMessage()
取得异常的堆栈信息(比较适合于程序调试阶段):printStackTrace();
先看取得异常的堆栈信息printStackTrace()方法。看以下例子。
import java.io.*;
public class ExceptionTest07{
public static void main(String[] args){
try{
FileInputStream fis = new FileInputStream("c:/ab.txt");
}catch(FileNotFoundException e){
//打印异常堆栈信息
//一般情况下都会使用该方式去调试程序
e.printStackTrace();
}
//这段代码会执行
System.out.println("ABC");
}
}
编译运行后输出:
java.io.FileNotFoundException: c:\ab.txt (系统找不到指定的文件。)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at ExceptionTest07.main(ExceptionTest07.java:8)
ABC
再来看取得异常信息描述:getMessage()方法。
import java.io.*;
public class ExceptionTest07{
public static void main(String[] args){
try{
FileInputStream fis = new FileInputStream("c:/ab.txt");
}catch(FileNotFoundException e){
msg=e.getMessage();
System.out.println(msg);
}
System.out.println("ABC");
}
}
编译运行后输出:
c:\ab.txt (系统找不到指定的文件。)
ABC
从上面的例子可以看出,e.printStackTrace()比e.getMessage()的方法详细,前者输出的异常信息比后者完整,因此一般使用e.printStackTrace()来打印异常信息。捕捉了异常之后进行打印才能知道你的代码哪里出现了异常,才能不断地去修改完善自己的代码,也就是所说的一般使用e.printStackTrace()去调试程序。
接下来再补充一下方法的重写与异常的知识。
这块儿内容只要记着一个原则:重写的方法不能比被重写的方法抛出更宽泛的异常。结合以下例子来理解一下。
class A{
public void m1(){}
}
public class AB extends A{
//子类永远无法比父类抛出更宽泛的异常
public void m1() throws Exception{}
}
上述代码编译运行后出错:
AB.java:5: 错误: AB中的m1()无法覆盖A中的m1()
public void m1() throws Exception{}
^
被覆盖的方法未抛出Exception
1 个错误
这是因为子类永远无法比父类抛出更宽泛的异常。再看一个例子:
import java.io.*;
class A{
public void m1()throws FileNotFoundException{}
}
public class AB extends A{
public void m1()throws IOException{}
}
编译运行后出错:
AB.java:22: 错误: AB中的m1()无法覆盖A中的m1()
public void m1()throws IOException{}
^
被覆盖的方法未抛出IOException
1 个错误
父类中的m1()方法抛出FileNotFoundException异常,AB继承A,并且重写m1()方法,抛出IOException的异常,而我们知道,FileNotFoundException继承IOException,所以出错。
搜索微信公众号“程序员考拉”,欢迎关注!
Java 异常的处理方式--throws和try catch的更多相关文章
- “全栈2019”Java异常第九章:throws关键字详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- java中的throw、throws和try catch浅析
今天在公司和同事聊天的时候,突然发现自己对java中的throw.throws和try catch的作用理解不够准确,在网上查了查,在此大概梳理一下. throw用于抛出异常,例如 throw new ...
- java异常和throw和throws的区别
之前在编程中编译完成后,运行时,会遇见一些常见的错误,如NullPointerException,ArrayIndexOutOfBoundsException等等 在今天重新回顾学习了java异常,总 ...
- JAVA异常及其异常处理方式
异常处理 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的.比如说,你的代码少了一个分号,那么运行出来结果是提示是错误 java.lang.Error:如果你用Syste ...
- java异常中throw和throws的区别
throws和throwthrows:用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁. 用在方法声明后面,跟的是异常类名 可以跟多个异常类名,用逗号隔开 表 ...
- java异常——五个关键字(try、catch、finally、throw、throws)
一.try.catch.finally常用组合 try{ xxx }catch(xxxException e){ e.printStackTrace(); } try{ xxx }catch(xxxE ...
- “全栈2019”Java异常第八章:throw关键字详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- Java异常题库
一.填空题 __异常处理__机制是一种非常有用的辅助性程序设计方法.采用这种方法可以使得在程序设计时将程序的正常流程与错误处理分开,有利于代码的编写和维护. 在Java异常处理中可以使用多个catch ...
- Java异常之try,catch,finally,throw,throws
Java异常之try,catch,finally,throw,throws 你能区分异常和错误吗? 我们每天上班,正常情况下可能30分钟就能到达.但是由于车多,人多,道路拥挤,致使我们要花费更多地时间 ...
随机推荐
- bzoj4199: [Noi2015]品酒大会(后缀数组)
题目描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战 两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainb ...
- Linux 下 SSH 远程超时解决方案
Linux 下 SSH 远程超时解决方案 今天突然看到一个问题说是如何解决SSH远程超时的问题. 找了一点资料.用于解决这个需求~ 第一种:OpenSSH 配置文件设置 位于112行的 "C ...
- iOS tableview性能优化及分析
1.最常用的就是cell的重用, 注册重用标识符 每次滑动cell时需要先去缓存池中寻找可循环利用的cell,如果没有则再重新创建cell 2.减少cell中控件的数量 view对象尽量缩减控件的数量 ...
- PHP开发微信公众号(二)消息接受与推送
上一篇文章我们知道怎么获取二维码,这样别人就可以扫描二维码来关注我们,但是别人关注后,发送消息,我们怎么进行相关处理? 这里我们就来学习下怎么处理处理这些消息,以及推送消息. 学习之前首先你需要有一个 ...
- CocoaPods的PodSpec.json文件用法
最近有时候用最新的CocoaPod的第三方库,有时候发现CocoaPod.org能搜到那个Podfile,但是每次在终端Pod search xxx,每次都搜不到,原来是本地的Podspec没用更新, ...
- Kettle 值映射
在费用转换里面做了两个值映射.一个是编码.一个是名称.其中两个值映射设置不一样效果不一样. 第一个编码映射 目标字段名不为空,则表示会新增字段.其中复核源值条件的都会转换为目标值,不符合条件的会用[不 ...
- Django get_object ,get_queryset方法
Django提供了很多通用的基于类的视图(Class Based View),可以帮我们简化执行以下操作的代码.这些基于类的视图还提供了get_queryset, get_context_data和g ...
- 第十次 Scrum Meeting
第十次 Scrum Meeting 写在前面 会议时间 会议时长 会议地点 2019/4/16 14:30 30min 新主楼F座2F 附Github仓库:WEDO 例会照片 工作情况总结 人员 上阶 ...
- 添加ASP.NET网站资源文件夹
ASP.NET应用程序包含7个默认文件夹,分别为Bin.APP_Code.App_GlobalResources.App_LocalResources.App_WebReferences.App_Br ...
- POI基本操作
1.读取excel文件 InputStream is = new FileInputStream(filesrc); POIFSFileSystem fs = new POIFSFileSystem( ...