java try catch 例子_java try catch

try catch机制非常好。那些觉得try catch不行的人,是他们自己的水平有问题,无法理解这种机制。并且这群人写代码不遵守规则,喜欢偷懒,这才造成try catch不好的错觉。

详细解释:

1.程序要健壮,必须要设计报错机制。

最古老,也是最常见的,比如:

bool CreateFile( );

//如果创建文件失败就返回false,否则返回true。

这种报错方式,显然不好。因为它没有给出产生错误的具体原因。

2.改进:一个函数或过程,会因为不同的原因产生错误,报错机制必须要把这些错误原因进行区分后,再汇报。

比如:

int CreateFile():

//如果创建成功就返回1.

//如果是因为没有权限,导致失败,返回-1。

//如果是因为文件已经存在,导致失败,返回-2。

//如果是因为创建文件发生超时,导致失败,返回-3。

这样看上去,比【1】要好些,至少指出了比较具体的失败原因,但是,还不够。

3.很多情况下,函数需要把详细的原因,用字符串的方式,返回:

class Result

{

....int State;//同【2】

....string ErrorMessage;//如果失败,这里将给出详细的信息,如果有可能,应该把建议也写上去。

}

Result CreateFile();

//如果创建成功,返回的Result,State为1,ErrorMessage为null。

//如果是因为没有权限,导致失败,返回的Result,State为-1,ErrorMessage为"用户【guest】没有权限在【C:\】这个目录下创建该文件。建议您向管理员申请权限,或者更换具有权限的用户。"。

//如果是因为文件已经存在,导致失败,返回的Result,State为-2,ErrorMessage为"文件【C:\abc.txt】已经存在。如果需要覆盖,请添加参数:arg_overwrite = true"。

//如果是因为创建文件发生超时,导致失败,返回的Result,State为-3,ErrorMessage为"在创建文件时超时,请使用chkdsk检查文件系统是否存在问题。"。

4.我个人推崇上面这种方式,完整,美观。但是这种流程,容易与正常的代码混在一起,不好区分开。因此,Java、C#等设计了try catch这一种特殊的方式:

void CreateFile()

//如果创建成功就不会抛出异常。

//如果是因为没有权限,导致失败,会抛出AccessException,这个Exception的Msg属性为"用户【guest】没有权限在【C:\】这个目录下创建该文件。建议您向管理员申请权限,或者更换具有权限的用户。"。

//如果是因为文件已经存在,导致失败,会抛出FileExistedException,这个Exception的Msg属性为"文件【C:\abc.txt】已经存在。如果需要覆盖,请添加参数:arg_overwrite = true"。

//如果是因为创建文件发生超时,导致失败,会抛出TimeoutException,这个Exception的Msg属性为"在创建文件时超时,请使用chkdsk检查文件系统是否存在问题。"。

可见,上述机制,实际上是用不同的Exception代替了【3】的State。

这种机制,在外层使用时:

try

{

....CreateFile( "C:\abc.txt" );

}

catch( AccessException e )

{

....//代码进入这里说明发生【没有权限错误】

}

catch( FileExistedException e )

{

....//代码进入这里说明发生【文件已经存在错误】

}

catch( TimeoutException e )

{

....//代码进入这里说明发生【超时错误】

}

对比一下【3】,其实这与【3】本质相同,只是写法不同而已。

5.综上,我个人喜欢【3】这类面向过程的写法。但很多喜欢面向对象的朋友,估计更喜欢【4】的写法。然而【3】与【4】都一样。这两种机制都是优秀的错误处理机制。

6.理论说完了,回到正题,题注问:为什么不用try catch?

答:这是因为,很多菜鸟,以及新手,他们是这样写代码的:

void CreateFile( )

//无论遇到什么错误,就抛一个 Exception,并且也不给出Msg信息。

这样的话,在外层只能使用:

try

{

....CreateFile( "C:\abc.txt" );

}

catch( Exception e )

{

....//代码进入这里说明发生错误

}

当出错后,只知道它出错了,并不知道是什么原因导致错误。这同【1】。

以及,即使CreateFile是按【4】的规则设计的,但菜鸟在外层是这样使用的:

try

{

....CreateFile( "C:\abc.txt" );

}

catch( Exception e )

{

....//代码进入这里说明发生错误

....throw Exception( "发生错误" )

}

这种情况下,如果这位菜鸟的同事,调用了这段代码,或者用户看到这个错误信息,也只能知道发生了错误,但并不清楚错误的原因。这与【1】是相同的。

出于这些原因,菜鸟的同事,以及用户,并没有想到,造成这个问题是原因菜鸟的水平太差,写代码图简单省事。他们却以为是try catch机制不行。

因此,这就导致了二逼同事,以及傻比用户,不建议用try catch。

通常try/catch适用于以下场景:

在代码中对可预见而又无法掌控的情况进行处理。比如在SOCKET BIND时发现端口已经被占用了、或者IO在打开文件时发现文件不存在,就需要在catch中做适当的处理避免程序crash掉;

将问题向更上一层面传递,将处理权让渡给caller。假如你写了个ORM FRAMEWORK,在delete的时候发现外键关联删除失败,FRAMEWORK不能擅自替上层的代码决定该怎么办,于是只好把DB的报的错误原样(或者加层外衣)throw出来,调用者根据业务需要选择处理方式;

除此之外,所有问题应该由程序员主动判断,就地解决。在规模比较大的软件中,定义自己的Exception体系并正确、克制地使用try/catch,可以让代码变得易读易维护还美观。

传递给上层来解决例子如下:

void handlearray(int a[]) throws Npe

{

if(a==null)

throw new Npe();

a[0]……//处理部分

}

上层:

try{

handlearray(a);

}catch(E… e)

{

//对a进行处理。

}

这时候传入数组为空,这个错误不是你当前这个函数所能处理的,只能是抛给上层,也就是生成这个数组,或者能对这个数组负责的那部分代码,让上层去处理,上层去try cacth,并在catch中对异常处理,类库中类似的像文件io的时候很多读写类都会抛出FileNotFoundException,也是一个道理,当上层给我一个找不到的文件,那在我的io类中肯定无法处理你这个异常,只能抛到给我这个文件的那一层,让那一层的代码对这个问题进行反应。

当然有些时候不需要,比如:

void makearray(int a[])

{

a=new int[];

……//生成部分

if(a==null)

……//处理部分,此处一般不用抛异常,直接可以在这一层处理掉。

}

像这个就不一样了,因为这次发生的问题是在我这一层代码所能控制之内的,所以我直接把问题处理掉就好了,没必要给上层了。

为什么讲“正确”并“克制”地使用?因为有些又蠢又懒的程序员喜欢这么干:

将函数所有代码都放到try{}之中,哪怕 int i = 1这种赋值的都不放过。然后在catch里输出一个错误信息就万事大吉。这样看起来是很省心哇,不用动脑子去分析哪里可能发生什么错误,反正所有错误都在catch的掌控之中;

用try/catch来控制流程。举个简单的例子,假设有这么个要求:

将字符串转换成数字,并返回该数字的绝对值,如果出错了就返回-1. 于是乎,就能见到类似下面代码的奇葩做法:

int parse_number(const char* s){

try{

return abs(atoi(s));

}catch(Exception){

return -1;

}

}

这多省事儿,不用考虑s是不是NULL、不用考虑s是不是包含非数字的字符、不用考虑s是不是超出int的取值范围...我是个优秀的程序员耶~~,我的代码好简洁。

try/catch和errno可以结合起来使用,二者不是非此即彼的关系,比如在某些场景下,可以将不确定的错误简化归纳为固定的errno输出,调用者直接检查返回的errno即可,简化了代码,也减轻了负担。比如某函数,成功返回0,失败返回-1:

int foo(double d){

try{

do_something(d);

return 0;

}catch(Exception){

return -1;

}

}

void bar(double d){

int result = foo(d);

if(result == -1) return;

do_next_steps();

}

三、细节

Java中try,catch,finally的用法

Java异常处理的组合方式:

1.try+catch

运行流程:运行到try块中,如果有异常抛出,则转到catch块去处理。然后执行catch块后面的语句

2.try+catch+finally

运行流程:运行到try块中,如果有异常抛出,则转到catch块,catch块执行完毕后,执行finally块的代码,再执行finally块后面的代码。

如果没有异常抛出,执行完try块,也要去执行finally块的代码。然后执行finally块后面的语句

网上有很多人探讨Java中异常捕获机制try...catch...finally块中的finally语句是不是一定会被执行?很多人都说不是,当然他们的回答是正确的,经过我试验,至少有两种情况下finally语句是不会被执行的:

(1)try语句没有被执行到,如在try语句之前就返回了,这样finally语句就不会执行,这也说明了finally语句被执行的必要而非充分条件是:相应的try语句一定被执行到。

(2)在try块中有System.exit(0);这样的语句,System.exit(0);是终止Java虚拟机JVM的,连JVM都停止了,所有都结束了,当然finally语句也不会被执行到。

四、检查型异常和非检查型异常

8f8e0178f886

Paste_Image.png

上图摘自Java 进阶 之 检查型异常与非检查型异常

直接继承 Exception 的异常,属于检查型异常,必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。如IOException,SQLException

继承自Runtime Exception或 Error 的是非检查型异常,可以不用捕获

1、throws出现在方法函数头;而throw出现在函数体。

2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。

3、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/501628.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java xss 默认值_一台 Java 服务器可以跑多少个线程?

原标题:一台 Java 服务器可以跑多少个线程?转自:简书,作者:新栋BOOK一台Java服务器能跑多少个线程?这个问题来自一次线上报警如下图,超过了我们的配置阈值。京东自研UMP监控分析打出jstack文件&…

java设计模式初探之装饰者_JAVA设计模式初探之装饰者模式

装饰者模式1、意图: 动态地给一个对象添加一些额外的职责。就增加功能来说, Decorator模式相比生成子类更为灵活。该模式以对客 户端透明的方式扩展对象的功能。2、适用环境(1)在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责…

redis在java中的方法_redis在java中的使用方法

Redis是key-value方式储存数据的内存数据库。下载后解压,redis-server.exe是redis服务,启动之后就可以使用redis。redis-cli.exe是客户端,可以访问本地或远程的redis。redis-cli.exe -h 127.0.0.1 -p 6379 命令行命令。修改-h后的ip…

Java写一个快速排序_快速排序java实现

1.快速排序的思想快速排序属于交换排序,是冒泡排序的升降版。相对于冒泡排序而言,快速排序增大了记录比较和移动的距离,将关键字较大的记录直接移动到后面,将关键字较小的记录直接移动到前面;不再是相邻两个记录依次进…

java porm.xml_通过Maven仓库安装Spire.PDF for Java

本文将介绍如何通过Maven仓库安装Spire.PDF for Java。首先,在pom.xml文件中配置Maven仓库路径。com.e-icebluee-icebluehttp://repo.e-iceblue.com/nexus/content/groups/public/其次,在pom.xml文件中指定Spire.PDF for Java的Maven依赖e-iceblue spire…

JAVA入门级教学之(方法内存分配机制)

目录 JAVA入门级教学之(方法内存分配机制) 1.方法只定义,不调用,是不会执行的 2.在JVM内存划分上有这样三块主要的内存空间:【还有其它的内存空间】 3.关于"栈"数据结构 4.方法代码片段存在哪里?…

cad与连接mySQL数据库_跨服务器操作数据库?其实很简单!(下)

之前一篇文章一步一步的教小伙伴们如何建立SQL Server的数据库链接(DBLINK),详细步骤可查看上篇:跨服务器操作数据库?其实很简单!(上)今天我们来教大家如何连接MYSQL和Oracle的远程数据库创建MYSQL远程链接第一步需要下载MYSQL驱动…

php如何获取服务器时间_php如何获取当前日期

1、前提条件php网站编程中,我们一般用date函数来获取服务器上的时间。但要想正确调用date函数,必须保证php的配置文件php.ini已经配置正确了,否则调用date函数时会报错,没办法正确进行获取时间。2、用记事本程序打开php配置文件ph…

JAVA入门级教学之(对象的创建和使用)

/* 对象的创建和使用*/ public class OOTest01 {public static void main(String[] args){//通过一个类可是实例化N个对象//实例化对象的语法:new.类名();//new是java语言中的一个运算符//new运算符的作用是创建对象,在JVM【堆】内存中开辟新的内存…

JAVA入门级教学之(对象的使用)

//定义一个用户类public class User {//属性【以下都是成员变量之实例变量】//用户编号//int是一种【基本数据】类型:整数型//no是一个实例变量int no;//用户名//String是一种引用数据类型:代表字符串//name是一个实例变量//name是一个引用String name;/…

台式电脑耳机插孔在哪_一图教你学会电脑主机后面各接口正确接线

电脑主机后面接口众多,很多人分不清各接口都分别起什么作用和怎么接线,下面就来重点说说经常易出错的各接口作用及连接方法。1、 键盘鼠标接口:注意紫色的圆形接口为键盘接口,绿色的圆形接口为鼠标接口。如果你的键盘是紫色的圆形…

软件加入使用时间_你有了抢口罩软件,电商也进行了升级,我们又有了新软件(3月2日更新)...

超神office新鲜一手办公、软件教程你有了抢口罩软件,电商也进行了升级,我们又有了新软件(3月2日更新)”昨天的软件,作者又迎来了更新,功能增加,具体表现还需要各位评测。01新软件介绍一、软件界面秒抢助手内测版&#…

JAVA入门级教学之(内存引用的例子)

先定义一个地址类 public class Address {//地址String addr; } 内存引用的例子 public class OOTest03 { public static void main(String[] args){//u是引用//u是局部变量User unew User();//上一个版本编写//u.addrnew Address();//可以通过前章内存示意图看出其中的原…

小米10开始抓取日志怎么关闭_除了*#*#6485#*#*,小米手机还有这些神秘暗号

最近在小米社区(xiaomi.cn)平台,一条快速查看手机电池信息的代码,居然成了大家广泛关注和讨论的焦点,甚至很多米粉也晒出了自己的界面截图,同时关于电池使用寿命和损耗的问题也被频频提及。而除了这条代码之外,小米手机…

java多线程打印helloworld,Java并发编程--多线程之HelloWorld

上篇博客我们介绍了一些基本概念,进程、线程、并发。下面我们开始写第一个多线程的程序。两种方式:一、实现Runnable接口;二、基础Thread类。一、实现Runnable接口package com.tgb.klx.thread;public class hello1 implements Runnable {publ…

禁售苹果手机_苹果、华为供应商工厂突发火灾!浓烟冲天

网友曝料,9月7日上午,位于江苏昆山的欣兴电子旗下鼎鑫电子的一处工厂突然发生火灾,现场浓烟滚滚。 根据欣兴电子发布的公告,昆山鼎鑫电子工厂今天上午10时50分发生火灾,起火点疑似在生产传统PCB的一…

JAVA入门级教学之(内存中的空指针异常)

空指针异常示例: //定义一个顾客类测试空指针异常public class Customer {int id; } /*空指针异常示例*/ public class OOTest04 {public static void main(String[] args){Customer cnew Customer();System.out.println(c.id);//0cnull;//空指针演示//以下程序【…

炫界 (795) -(脸兵马俑)_秦兵马俑彩绘脱落背后的秘密: 粘合剂竟然是动物胶与蛋类混合...

秦兵马俑表面都曾经涂有绚丽的彩绘,然而在两千多年埋藏过程中,大部分彩绘被破坏。近日,西北大学与秦始皇帝陵博物院共同发布了最新研究成果,为日后兵马俑彩绘的保护和修复提供了依据。要保护彩绘层,就必须了解彩绘层里…

c++对数函数_DS-K1T105M-C 海康威视考勤门禁一体机 支持刷卡+密码 DS-K1T105E/M/C-C

DS-K1T105E 海康威视刷卡式考勤门禁一体机 主机支持刷卡、刷卡密码、开门按钮等多种开门方式 DS-K1T105E-C DS-K1T105M DS-K1T105M-C DS-K1T105C DS-K1T105C-CDS-K1T105E/M/C-C海康门禁考勤一体机海康门禁考勤一体机 DS-K1T105E/M/C-C 产品简介DS-K1T105E/M/C/S-C是海康最的新研…