java中异常的处理
异常分为运行时的异常和检测异常:
java提供了两种异常机制。一种是运行时异常(RuntimeExepction),一种是检查式异常(checked execption)。
运行时的异常就是在java虚拟机正常运行的时候抛出的异常:
常见的五类运行时的异常:
IllegalArgumentException,
NullPointerException
ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常
ClassCastException 试图将对象强制转换为不是实例的子类时,抛出该异常
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数
IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出
NoSuchElementException 表明枚举中没有更多的元素
NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
等
运行时的异常主要是由于程序员的逻辑错误引起的,这个时候就会导致程序的异常退出,例如android界面的空指针异常。
1、对应运行时的异常,我们可以使用 try catch进行处理,也可以不处理,要么是线程中止,要么是主程序终止。
我们来看两个常用的运行时的异常:
列如自己定义可一个模块,提供给别人调用的时候,我们一定要进行输入参数的判断:
public static void copyDirectoryToDirectory(File srcDir, File destDir) throws IOException {
if (srcDir == null) {
throw new NullPointerException("Source must not be null");
}
if (srcDir.exists() && srcDir.isDirectory() == false) {
throw new IllegalArgumentException("Source '" + destDir + "' is not a directory");
}
//...
}
这个时候我们就可以抛出一个运行时的异常NullPointerException直接终止程序。
运行时异常的常用案例二:
public static GateWayCaller getGateWayCaller(String serviceKey) { if("alerting".equals(serviceKey)) { return new AlertingCaller(); } else if("report".equals(serviceKey)) { return new ReportCaller(); } //... else { return null; } }
当调用者调用的时候,它不知道你会返回一个null对象,如果调用者没有对返回的值进行判断null的处理,就要引起空指针异常,所以写代码的时候,我们尽量不要使用返回null的处理,这里我们可以创建一个运行时的异常,直接退出程序
if("alerting".equals(serviceKey)) return new AlertingCaller(); else if("report".equals(serviceKey)) return new ReportCaller(); //... else throw new RuntimeException("Invalid Service Key!");
运行时的异常案例3:在java web开发中数据库dao层不对异常进行任何处理,将异常抛出,在业务层中对异常进行处理,如果不要继续把异常throws给调用者,就直接抛出一个运行时的异常
package com.weiyuan.goods.user.dao; import java.sql.SQLException; import org.apache.commons.dbutils.handlers.ScalarHandler; import cn.itcast.jdbc.TxQueryRunner; public class UserDao { //操作数据库
private TxQueryRunner qr = new TxQueryRunner(); /***
* 查询用户名是否存在
* @throws SQLException
*/
public boolean ajaxValidateLoginName(String loginName) throws SQLException{
//获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
String sql ="select count(*) from t_user where loginname=?";
Number num = (Number) qr.query(sql, new ScalarHandler(),loginName);
int count = num.intValue();
if(count>0){
return true;
}
return false;
} /***
* 查询邮箱是否存在
* @throws SQLException
*/
public boolean ajaxValidateEmain(String email) throws SQLException{
//获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
String sql ="select count(*) from t_user where email=?";
Number num = (Number) qr.query(sql, new ScalarHandler(),email);
int count = num.intValue();
if(count>0){
return true;
}
return false;
} }
在业务层对异常进行处理,业务层不要通知调用者存在业务,在对异常进行处理的时候抛出一个运行时的异常
package com.weiyuan.goods.user.service; import java.sql.SQLException; import javax.management.RuntimeErrorException; import com.weiyuan.goods.user.dao.UserDao; public class UserService { private UserDao dao = new UserDao(); public boolean ajaxValidateLoginName(String loginName) { try {
return dao.ajaxValidateLoginName(loginName);
} catch (SQLException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e.getMessage());
} } public boolean ajaxValidateEmail(String email) { try {
return dao.ajaxValidateLoginName(email);
} catch (SQLException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e.getMessage());
} }
}
检测异常也叫做非运行时候的异常,常见的非运行的异常有下面的几种形式,类型上都属于Exception类及其子类
IOException
SQLExCeption
用户自定义的异常
使用try…catch…finally语句块进行捕获
在产生异常的方法所在的方法声明throws Exception
1.throws是表明方法抛出异常,需要调用者来处理,如果不想处理就一直向外抛,最后会有jvm来处理;
2.try catch 是自己来捕获别人抛出的异常,然后在catch里面去处理;
对应检测异常,操作系统要求我们必须对其处理,要不使用try catch 处理 要不使用throws进行声明由调用者进行处理
我们来看一个检测的异常的例子
第一种对异常进行声明:
public boolean ajaxValidateEmail(String email) throws SQLException{
//获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
String sql ="select count(*) from t_user where email=?";
Number num = (Number) qr.query(sql, new ScalarHandler(),email);
int count = num.intValue();
if(count>0){
return true;
}
return false;
}
第二种对异常进行逻辑处理
/***
* 查询邮箱是否存在
* @throws SQLException
*/
public boolean ajaxValidateEmail(String email){
//获得满足记录的数目是对象,返回一个整数,整数是单行单列使用ScalarHandler
String sql ="select count(*) from t_user where email=?";
Number num;
try {
num = (Number) qr.query(sql, new ScalarHandler(),email);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int count = num.intValue();
if(count>0){
return true;
}
return false;
}
第三种自定义异常:
自定义异常通常是定义一个继承自Exception类的子类。一般情况下我们都会直接继承自Exception类,而不会继承某个运行时的异常类。
5.1、创建自定义异常:
public class MyException extends Exception{
public MyException(){
super();
}
public MyException(String msg){
super(msg);
}
}
对应非运行的异常,都代表了一个异常的场景,作为程序员不能直接使用一个Exception进行进行处理,而应该对每一个异常场景进行处理,例如:
try { } catch (SQLException e) { }catch(FileNotFoundException){ }
不要直接:
try { } catch (Exception e) {
也不能直接将所有的异常都统一使用一个Exception跑出去
public boolean ajaxValidateEmail(String email) throws FileNotFoundException, SQLException{
不能写成
public boolean ajaxValidateEmail(String email) throws Exception{
4 对应函数的返回值和异常的区别
含义的返回值是一个业务操作成功返回的结果,不能把返回值作为一个业务是否执行成功的标志,例如 如果返回值是true就表示业务执行成功,这是错误的,如果返回值是true表示的是该业务的返回值就是true,
通过异常我们可以知道这个业务失败的原因
User login(String username, String password); throws UserNotFoundException, PasswordNotMatchException; 这个模块的功能定义,不能通过函数的返回值来确定函数释放成功,返回值是表示函数内部逻辑处理的返回结果,通过异常来表示函数的操作是否失败,失败的原因是啥。
案例3:对应throws new Exception 和 throws new RuntimeException 的区别
1、在业务操作的时候,如果业务操作失败,我们应该抛出throws new Exception提示用户业务操作失败的原因。抛出throws new Exception 就是业务层需要将业务失败的异常通知调用者,让调用者对异常进行处理
2、但是在业务操作的过程中,如果是系统异常,列如sql数据库的异常,它不是业务失败的异常,这个时候业务层不应该将异常通过通知调用者,但是它又是异常,这个时候直接 throw new RuntimeException 直接退出程序,禁止业务的操作。
我们来看用用户注册的时候,会发送邮件到用户的邮箱,当用户点击邮件的激活的时候,会将激活码携带到后台,后台收到验证码之后会和保存到数据库中该用户的初装的激活码进行对比,如果相同设置用户的集合状态为true
激活的业务操作的结果就是下面的三种:
1、激活成功
2、激活码无效
3、用户以前就已经激活过,不能重复注册
我们来看程序的代码:
dao层、通过激活码查找用户,将用户的激活状态设置成true
/*
* 通过激活码获得用户
* */
public User findUserByActivationCode(String activationCode) throws SQLException{ String sql = "select * from t_user where activationCode = ?";
return qr.query(sql, new BeanHandler<User>(User.class),activationCode);
} /*
* 设置用户的激活状态
* */ public void setUserActivationCode(String uuid,int status) throws SQLException{
String sql = "update t_user set status = ? where uid = ? ";
qr.update(sql,status,uuid);
}
业务层的操作
/*设置用户的激活状态*/ public void activation(String activationCode) throws Exception{
//1 、通过激活码查找对应的用户信息
try {
User user = dao.findUserByActivationCode(activationCode);
if(user == null){
throw new Exception("无效的激活码");//业务异常,业务失败
}
if(user.getStatus()== 1){
throw new Exception("用户已经既激活,不要二次激活");//业务异常,业务失败
}
dao.setUserActivationCode(user.getUid(), 1); //1表示激活
} catch (SQLException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e.getMessage()); // 不是业务的异常吗,而是电脑环境系统数据库的异常,直接退出线程,无法进行业务的操作了
} }
控制层:
/*
* 当用户从邮箱点击的激活的时候会调用该方法,并且把激活码传递过来
*
* */
public String activation(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub String activationCode = request.getParameter("activationCode");
System.out.println("email activationCode is :"+activationCode);
try {
service.activation(activationCode);
//激活成功
request.setAttribute("code", "success"); //msg.jsp已经code的值来显示错误信息还是正确的信息
request.setAttribute("msg", "激活成功");
return "f:/jsps/msg.jsp";
} catch (Exception e) {
//将业务操作的异常信息在msg.jsp中显示出来
String msg = e.getMessage();
request.setAttribute("code", "error"); //msg.jsp已经code的值来显示错误信息还是正确的信息
request.setAttribute("msg", msg);
return "f:/jsps/msg.jsp"; } }
通过代码:我们就可以知道,在业务层中,业务失败存在两种异常:
throw new Exception("无效的激活码");//业务异常,业务失败
throw new Exception("用户已经既激活,不要二次激活");//业务异常,业务失败
这两种异常是业务操作失败的异常,我们需要通知servlet进行处理,提示业务操作的结果,
但是对应dao层抛出的
SQLException 的异常,不是业务操作的结果,我们不需要让调用者知道该异常,但是我们必须对该异常处理,所以抛出
throw new RuntimeException(e.getMessage()); // 不是业务的异常吗,而是电脑环境系统数据库的异常,直接退出线程,无法进行业务的操作了
这就是
throw new RuntimeException 和 throw new Exception的区别,
throw new RuntimeException就是不需要让调用者知道的异常,但是内部需要需要对例如对sql异常进行处理,所以就抛出throw new RuntimeException
转载于:https://www.cnblogs.com/kebibuluan/p/6816980.html
java中异常的处理的更多相关文章
- 《java中异常和错误》
异常和错误的区别. 异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,你(开发 ...
- 浅谈java中异常抛出后代码是否会继续执行
问题 今天遇到一个问题,在下面的代码中,当抛出运行时异常后,后面的代码还会执行吗,是否需要在异常后面加上return语句呢? public void add(int index, E element) ...
- java中异常的抛出:throw throws
java中异常的抛出:throw throws Java中的异常抛出 语法: public class ExceptionTest{ public void 方法名(参数列表) throws 异常列表 ...
- Java中异常关键字throw和throws使用方式的理解
Java中应用程序在非正常的情况下停止运行主要包含两种方式: Error 和 Exception ,像我们熟知的 OutOfMemoryError 和 IndexOutOfBoundsExceptio ...
- java中异常以及处理异常
一.异常简介 什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域的情况,称之为异常. java中异常的体系是怎么样的呢? 1.Java中的所有不正常类都 ...
- [转载]Java中异常的捕获顺序(多个catch)
http://blog.sina.com.cn/s/blog_6b022bc60101cdbv.html [转载]Java中异常的捕获顺序(多个catch) (2012-11-05 09:47:28) ...
- Java中异常的基本应用(一)
在Java中,我们把异常当做一种对象来处理,正是异常机制的引入,使得我们的程序更加健壮.异常指示了一个不正常的条件,或者一个错误条件,简单地说就是一个中断了正常的指令流的事件.程序控制将无条件的抛至一 ...
- Java基础知识强化24:Java中异常
1.什么是异常 ? Java程序运行中,常常会遇到非正常的现象,这种情况称为运行错误.根据性质可以分为错误和异常.Java程序中(无论谁写的代码),所有抛出(throw)的异常都必须从Th ...
- java中异常的面试
https://blog.csdn.net/qq_36523638/article/details/79363652 1) Java中的检查型异常和非检查型异常有什么区别? 这又是一个非常流行的Jav ...
- JAVA中异常状况总结
之前在<会当凌绝顶>这本书中学到过对于异常处理的知识,当时也是根据书上的代码,自己进行编写大概知道是怎么回事儿,王老师给我们上了一节课之后,发现异常处理可以发挥很大的作用. 通过在网络上 ...
随机推荐
- Java数组模拟队列
队列 先进先出 什么意思呢? 我的理解:队列就是一个数组(不包含链表),然后我们给它施加一个存数据和取数据的规则 当只允许从一端存数据,从另一端取数据的数组,就是队列,我们要做的就是给这个数组施加我们 ...
- Linux系统安装Dos系统(虚拟机里装)
结合以下两篇优秀的文章就能完成任务. 1.https://www.jb51.net/os/609411.html 2.http://blog.51cto.com/6241809/1687361 所需要 ...
- 用robotframework 标准库String解决由于存在千分位分隔符导致两个数值不相等的问题。
在编写robotframework自动化断言的过程中,我遇到了如下问题: 我想写一个两个金额判断是否相等的断言,其中一个金额是展示字段存在千分位分隔符,另一个金额是input带入字段,没有千分位分隔符 ...
- python3(十一)generator
# 只要把一个列表生成式的[]改成() L = [x * x for x in range(10)] print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] g ...
- docker安装GD扩展
apt update #更新软件源 apt install -y libwebp-dev libjpeg-dev libpng-dev libfreetype6-dev #安装各种库 docker-p ...
- 通过bat文件 进行mysql 连接 或者 操作涉及 密码的,如果密码 中有 % 号的话要特殊处理
比如我想在bat文件中进行一个数据库的连接 或者进行一个数据库中的 数据 导入或者导出(mysqldump) 这样子都会用到数据库密码, 假如这个数据库的密码 中又有 % 的话就要特殊转义一下才行执行 ...
- MD5中使用16进制
MD5中使用16进制消息摘要 分类: java_secruity2012-12-28 13:11 719人阅读 评论(0) 收藏 举报 消息摘要 由于数据在计算机中的表示,最终以二进制的形式存在,所以 ...
- Linux知识再回顾
Linux再回顾 下面是自己之前centos7的笔记总结第二篇,第一篇是19年就写过了一些,记住Linux中一切皆文件. 这里提下,使用xshell+xftp来使用云服务器是很不错的,强烈建议小伙伴这 ...
- Pytorch自定义创建BP神经网络
class BPNet(nn.Module): def __init__(self, in_dim, n_hidden_1, n_hidden_2,\ n_hidden_3, n_hidden_4, ...
- Extjs简单的form+grid组合
采用的是Extjs4.2版本 http://localhost:49999/GridPanel/Index 该链接是本地连接,只是方便自己访问,读者无法正常访问. <script src=&qu ...