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中异常状况总结
之前在<会当凌绝顶>这本书中学到过对于异常处理的知识,当时也是根据书上的代码,自己进行编写大概知道是怎么回事儿,王老师给我们上了一节课之后,发现异常处理可以发挥很大的作用. 通过在网络上 ...
随机推荐
- RedHat 6.5 上将系统语言修改为中文
RedHat 6.5 上将系统语言修改为中文 1.打开终端,输入su -,键入密码,获取超级用户权限. 2.输入cd /etc/sysconfig,进入设置目录. 3.输入vi i18n,进入到配置文 ...
- mysql搭建主从复制(一主一从,双主双从)
主从复制原理 Mysql 中有一个binlog 二进制日志,这个日志会记录下所有修改了的SQL 语句,从服务器把主服务器上的binlog二进制日志在指定的位置开始复制主服务器所进行修改的语句到从服务器 ...
- python--算法相关
一.时间复杂度排序 1.O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) ...
- Linux 文件管理篇(四 文件查找)
显示脚本文件或者命令的路径 which 显示档案的路径(数据库中查找,较快) ...
- 中阶d03.3 JDBC_CURD_Util --- 使用 junit执行单元测试(增删改查)
1.单元测试环境准备 https://www.cnblogs.com/longesang/p/11399010.html 2.测试 3.结果返回 4.代码 新建一个test目录统一存放测试案例 查: ...
- alg-最长回文字符串
class Solution { public: std::string longestPalindrome(const std::string& s) { if (s.empty()) { ...
- 【半监督学习】MixMatch、UDA、ReMixMatch、FixMatch
半监督学习(Semi-Supervised Learning,SSL)的 SOTA 一次次被 Google 刷新,从 MixMatch 开始,到同期的 UDA.ReMixMatch,再到 2020 年 ...
- Android调用系统设置
最近,弄了一下,调用系统设置的方法,Android4.0的系统,下面的所有设置项,都亲测可以调用.首先调用的方式如下: Intent mintent_setting_time = new Intent ...
- vuepress+gitee 构建在线项目文档
目录 快速入门 在现有vue项目中安装本地开发依赖vuepress 在现有vue项目根目录下创建docs目录 创建并配置文档首页内容 运行,查看效果 可能会出现vue和vue-server-rende ...
- 【简单了解系列】从基础的使用来深挖HashMap
HashMap定义 说的专业一点,HashMap是常用的用于存储key-value键值对数据的一个集合,底层是基于对Map的接口实现.每一个键值对又叫Entry,这些Entry分散的存储在一个由数组和 ...