赞
踩
异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。
程序错误分为三种:1.编译错误;2.运行时错误;3.逻辑错误。
异常处理机制能让程序在异常发生时,按照代码的预先设定的异常处理逻辑,针对性地处理异常,让程序尽最大可能恢复正常并继续执行,且保持代码的清晰。
Java的异常处理是通过5个关键字来实现的:try、catch、finally、throw和throws。
try-catch程序块的执行流程比较简单,首先执行的是try语句块中的语句,这时可能会有以下三种情况:
资料:
如果try块在执行过程中遇到异常,那么在try块中其余剩下的代码都将被忽略,系统会自动生成相应的异常对象,包括异常的类型、异常出现时程序的运行状态及对该异常的详细描述。如果这个异常对象与catch中声明的异常类型相匹配,则会把该异常对象赋给后面的异常参数,相应的catch块将会被执行。
异常对象常用的方法主要有以下两种:
try-catch语句块后加入finally块,把需要执行释放资源的语句放入finally块。它表示无论是否出现异常,都应当执行的内容。try-catch-finally语句的一般语法形式为:
try {
// 可能会发生异常的程序代码
} catch (Type1 id1){
// 捕获并处置try抛出的异常类型Type1
} catch (Type2 id2){
//捕获并处置try抛出的异常类型Type2
}finally {
// 无论是否发生异常,都将执行的语句块
}
try、catch、finally语句块的执行顺序:
注意:
finally 块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
一段代码可能会引发多种类型的异常,这是可以在一个try语句块后面跟多个catch语句块,分别处理不同的异常。但排列顺序必须是从子类到父类,最后一个一般是是Exception类。因为所有的异常子类都继承自Exception类,所以如果将父类异常放到前面,那么所有的异常都将被捕获,后面catch块中的子类将得不到被执行的机会。
如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。
throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。
throws语句的语法格式为:
methodname() throws Exception1,Exception2,..,ExceptionN {
}
方法名后的throws Exception1,Exception2,…,ExceptionN 为声明要抛出的异常列表。当方法抛出异常列表的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理。
使用throws关键字将异常抛给调用者后,如果调用者不想处理该异常,可以继续向上抛出,但最终要有能够处理该异常的调用者。
Throws抛出异常的规则:
throw总是出现在方法体中,用来抛出一个Throwable类型的异常。程序会在throw语句后立即终止,它后面的语句执行不到,然后在包含它的所有try块中(可能在上层调用函数中)从里向外寻找含有与其匹配的catch子句的try块。
异常是异常类的实例对象,我们可以创建异常类的实例对象通过throw语句抛出。该语句的语法格式为:
throw new exceptionname("exception");
注意,throw 抛出的只能够是可抛出类Throwable 或者其子类的实例对象。
如果抛出了可查异常,则还应该在方法头部声明方法可能抛出的异常类型。该方法的调用者也必须检查处理抛出的异常。
如果所有方法都层层上抛获取的异常,最终JVM会进行处理,处理也很简单,就是打印异常消息和堆栈信息。如果抛出的是Error或RuntimeException,则该方法的调用者可选择处理该异常。
throw和throws的区别表现在以下三个方面:
Java中的异常体系包括许多异常类,它们之间存在继承关系。Java的异常体系结构如图所示:
异常体系:
Throwable: Throwable类是java语言中所有错误或异常的超类,它派生两个子类:即 Error和Exception
Error类:表示仅靠程序本身无法恢复的严重错误,如内存溢出动态链接失败、虚拟机错误。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如图所示:
假如出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以在程序设计时,应该更关注Exception类。
Exception类:由Java应用程序抛出和处理的非严重的错误,如所需文件找不到、网络连接不同或中断、算术运算出错(如被0除)、数组下标越界、装载了一个不存在的类、对null对象操作、类型转换异常等。它的各种不同的子类分别对应不同类型的异常。
运行时异常:包括RuntimeException及其所有的子类,不要求程序必须对他们做出处理。如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)、ClassCastException(类型强制转换异常)、IllegalArgumentException(参数异常)、,ClassNotFoundException(找不到类异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。
非运行时异常 (编译异常):除了Exception中的RuntimeException及RuntimeException的子类以外,其他的Exception类及其子类(例如:IOException和ClassNotFoundException)都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
软件的运行过程离不开日志,日志主要用来记录系统运行过程中的一些重要的操作信息,便于监视系统 运行情况,帮助用户提前发现和避开可能出现的问题,或者出现问题后根据日志找到发生的原因。
日志根据记录内容的不同,主要分为三类:
log4j是一个非常优秀的日志记录工具。
通过log4j我们可以控制日志的输出级别,以及日志信息输送的目的地(如控制台、文件等),还可以控制每一条日志的输出格式。
log4j 是Apache的一个开源项目,官方网站是:http://logging.apache.org/log4j/1.2/,这里使用log4j 1.2.17版本,当前下载地址是:http://logging.apache.org/log4j/1.2/download.html,下载其中的zip文件并解压,里面包含的主要内容以及在zip包内的路径如下。
在项目中加入log4j所使用的jar文件。
在项目的src目录下,创建log4j.properties 文件
编写log4j.properties文件,配置日志信息
常用配置如下:
### 设置Logger输出级别和输出目的地 ### trace/debug/info/warn/error/,这个是输出的级别 log4j.rootLogger=debug, console,logfile ### debug表示最低的输出级别,更改此处,可以过滤日志输出的类型, ### console 表示输出到那个位置,此处表示输出到控制台, ### logfile 表示输出到文件, ### 类似console 和logfile可以有好几个,还可以写到数据库 ### 把日志信息输出到控制台 ### log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.Target=System.out log4j.appender.console.layout=org.apache.log4j.SimpleLayout # log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%p %m%n ####这里的p m n等符号都有特定含义,可查看手册 ### 把日志信息输出到文件:test.log ### log4j.appender.logfile=org.apache.log4j.FileAppender # 此处表示日志文件存储的文件名,可在项目刷新后进行查看test文件 log4j.appender.logfile.File=test.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n
在程序中记录日志信息。
首先需要创建一个私有静态的Logger对象,然后可以通过它的debug()或者error() 等方法输出日志信息了。
编写TestLog.java,代码如下:
public class TestLog { private int age; private static Logger log = Logger.getLogger(TestLog.class); public static void main(String[] args) { log.warn("构建对象"); TestLog test = new TestLog(); log.info("开始调用方法"); try { test.setAge(-1); }catch(Exception e) { log.debug(e.getMessage()); } log.error("调用结束"); } public int getAge() { return age; } public void setAge(int age) { if(age > 100 || age < 0) { throw new RuntimeException("年龄必须在0-100之间"); } this.age = age; } }
log4j配置文件中配置信息详细解释如下:
输出级别
log4j.rootLogger=debug, console,logfile
其中,dubug指的是日志记录器(Logger)的输出级别,主要输出级别及含义如下:
各个输出级别优先级:
fatal > error > warn > info > debug
日志输出的目的地 Appender
log4j.rootLogger=debug,console,logfile
其中,debug、logfile指的是日志输出目的地的名字。
log4j允许记录日志到多个输出的目的地,一个输出目的地被称为一个Appender。Log4j中最常用的Appender有以下两种:
如上的配置文件中共有两个Appender,第一个命名为console,使用了ConsoleAppender
,通过配置Target属性,把日志信息写到控制台System.out;第二个命名为logfile,使用了FileAppender
,通过配置File属性,把日志信息写到指定的文件test.log
中。
日志布局类型
Appender必须使用一个与之相关联的布局类型Layout,用来指定它的输出样式。log4j中最常用的Layout有以下三种:
上述配置文件中的第一个Appender是console,使用了SimpleLayout;第二个Appender是logfile,使用了PatternLayout,需要配置layout.ConversionPattern属性来自定义输出格式。
转换模式ConversionPattern
对应PatternLayout,需要配置layout.ConversionPattern属性,常用的配置参数以及含义如下:
Java异常机制可以保证程序更安全和更健壮。虽然Java类库已经提供很多可以直接处理异常的类,但是有时候为了更加精准地捕获和处理异常以呈现更好的用户体验,需要开发者自定义异常。
创建自定义异常类,语法格式:
public class [自定义异常类名] extends Exception{
}
示例代码如下:
public class GenderException extends Exception{
public GenderException(String message) {
super(message);
}
}
测试代码如下:
class Person { private String name = ""; // 姓名 private int age = 0; // 年龄 private String sex = "男"; // 性别 // 设置性别 public void setSex(String sex) throws GenderException { if ("男".equals(sex) || "女".equals(sex)) this.sex = sex; else { throw new GenderException("性别必须是“男”或者“女”!"); } } // 打印基本信息 public void print() { System.out.println(this.name + "(" + this.sex + "," + this.age + "岁)"); } } public class Test { public static void main(String[] args) { Person person = new Person(); try { person.setSex("Male"); person.print(); } catch (GenderException e) { e.printStackTrace(); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。