二、异常发生了
=======
来看程序清单3-1:
package com.cmower.java_demo.twelve;
public class Cmower {
public static void main(String[] args) {
System.out.println(2 / 0);
System.out.println(“程序已终止执行”);
}
}
/*****************************************
Exception in thread “main” java.lang.ArithmeticException: / by zero
at com.cmower.java_demo.twelve.Cmower.main(Cmower.java:6)
*****************************************/
当除数为0时,将抛出ArithmeticException异常,程序不再继续执行——异常信息打印得非常详细,我们可以找到哪一行出了错,并且知道错误是由于除数为0引发的;假如不知道错误怎么解决,可以把第一行的错误信息复制粘贴进行搜索,有不少答案正是你需要的。
三、异常处理
======
程序清单3-1没有使用异常处理机制,也可以顺利编译,因为ArithmeticException异常是非检查异常。那如果遇到检查异常呢?
编译器会提醒异常未处理,见下图:
那该如何处理异常呢?
如果是非检查异常,就需要在编码阶段对可能发生的错误进行规避,比如说,检查除数是否为0,如果为0就不要再做除法运算了。
如果是检查异常,做法大致有两种。
1.直接抛出错误
大学快毕业的时候,我感觉很迷茫,不知道未来要做什么,于是就打电话向父母求助,他们就劝我去一家软件培训园接受培训——自己决定不了的,就向上级请示。
这种现实的场景在Java中竟然也能找到相似之处。当一个方法不知道该怎么处理异常时,就可以使用throws关键字将编译器提醒的错误抛出,抛出的错误直接交给方法调用者来处理。示例如下:
public class Cmower {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream fileIn = new FileInputStream(“cmower.jpg”);
}
}
2.捕获错误
这种现实的场景在Java中仍然能找到相似之处。当一个方法知道自己该怎么处理异常时,就可以使用try块将编译器提醒出错的代码段进行捕获,然后在catch块中做出对应的处理。示例如下:
public class Cmower {
public static void main(String[] args) {
try {
FileInputStream fileIn = new FileInputStream(“cmower.jpg”);
}
catch (FileNotFoundException e) {
System.err.println(“读取的文件未找到:” + e.getMessage());
}
}
}
在我初学Java的时候,总喜欢直接捕获通用异常Exception,而不是特定的异常(比如FileNotFoundException),因为这样做很省事,除了少写几个字母之外,还不必担心其他异常出现时再另外捕获。
但这样做是有问题的。因为在日常的开发中,我们希望代码能够直观地体现出尽量多的信息,但不具体的Exception会隐藏掉那些应该呈现出来的信息。
四、异常处理的实战
=========
1.表单验证
当我们需要在服务器端对用户输入的内容进行检查时,就可以利用异常处理机制。怎么做呢?
第一步,自定义异常类,继承RuntimeException(那些不受检查的异常类都继承自该类)。
public class OrderException extends RuntimeException {
public OrderException() {
super();
}
public OrderException(String message) {
super(message);
}
}
第二步,表单验证的时候,遇到不符合要求的用户输入时使用throw关键字抛出自定义异常。
public static void check(String input) {
if (input == null) {
throw new OrderException(“输入值不能为空”);
}
if (input.length() < 10) {
throw new OrderException(“字符串长度不能少于10个”);
}
}
第三步,对自定义异常捕获,做出对应处理。
public class Cmower {
public static void main(String[] args) {
try {
check(args[0]);
}
catch (OrderException e) {
System.err.println(“用户输入条件有误:” + e.getMessage());
}
}
}
为什么要使用自定义异常来处理用户输入呢?因为用户输入需要检查很多项,而异常处理机制会在遇到第一项错误的时候就停下来,后面的代码是不会执行的——很贴合表单验证的场景。
2.使用日志记录异常的堆栈信息
在之前的例子当中,我们一直把错误信息打印在控制台,但正式的应用当中,日志是要被记录在日志文件中的,因为控制台记录的信息是有限的。
限于篇幅原因,日志相关的组件log4j、slf4j以及他们在项目中的配置请查阅资料。
当配置好日志组件后,就可以在需要记录日志信息的类中创建Logger,然后在catch块中使用logger.error(e.getMessage(), e);记录详细的异常堆栈信息。具体示例如下:
package com.cmower.java_demo.twelve;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Cmower {
protected static Logger logger = LoggerFactory.getLogger(Cmower.class);
public static void check(String input) {
if (input == null) {
throw new OrderException(“输入值不能为空”);
}
if (input.length() < 10) {
throw new OrderException(“字符串长度不能少于10个”);
最后
文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。
ut == null) {
throw new OrderException(“输入值不能为空”);
}
if (input.length() < 10) {
throw new OrderException(“字符串长度不能少于10个”);
最后
文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。