版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1 异常层次需要考察的异常情况有:用户输入错误、设备错误、物理限制、程序错误,传统的返回错误码的方法并不能处理所有的情况。1.1 异常分类在Java程序中,异常对象都派生于Throwable。如果Java的内置异常不满足需求,则可以创建自定义异常。下图是基本的异常体系:Error类描述了Java运行时系统的内部错误和资源耗尽错误,此类错误不应由应用程序抛出。而Exception分两类,一类是因程序逻辑问题,导致系统出问题,此时就是Runtime异常,如数组越界、类型转换错误、访问空指针。而如果程序可以正常,但在遇到不同IO情况时,出问题导致,则属于IO异常,如打开格式错误的URL、在文件尾部读
2、数据、加载不存在的类文件等。RuntimeException一定是程序写的有问题,是可以避免出现的。Java将Error和RuntimeException定义为未检查的异常。其他异常为已检查。编译器将检查代码是否为所有已检查异常提供异常处理器。1.2 异常声明方法应该在首部声明其所有可能抛出的异常,例如:public void lookup() throws XXException,YYException一个方法必须声明所有可能抛出的已检查异常,而未检查异常要么不可控,要么就应该避免发生。如果方法没有声明所有可能发生的已检查异常,编译器就会给出错误消息。当程序调用一个抛出已检查异常的方法、或程
3、序自己会抛出异常时,有必要进行异常声明,对于Error和Runtime这些未检查异常,无人可以预料,因此不需要声明。1.3 自定义异常如果遇到标准异常不能说明的情况,则需要自定义异常。只需要继承自某个异常类,并定义两个构造函数即可。一个默认构造函数,一个带有描述信息的构造器。2 捕获异常异常的捕获需要周密的计划。如果异常没有被捕获,程序会终止,并会在控制台上输出异常信息。对UI程序,异常出现后会提示用户,用户可以继续返回到程序中。使用try块来捕获异常trycatch(XXXException e)catch(YYYException e)如果try语句中的任何代码抛出一个在catch中指定的
4、异常,则程序会跳过try语句中的其余代码转而执行catch子句中的代码。如果抛出的是不在catch中指定的异常,则程序立即返回到上层调用者。当捕获到异常后,一种方法是我们自己处理;另一种是不处理,交给调用者去处理,这样只需要声明异常即可。如果应该捕获那些知道如何处理的异常,而将不知道如何处理的异常传递给上层。将异常交给足以胜任的处理器,比压抑它好得多。2.1 捕获多个异常通过示例代码,可以捕获多个异常2.2 链式异常当捕获到异常后,我们可以改变其类型,并重新抛出。这样做可以隐藏底层异常的细节,保持异常解释的抽象性。为了获得真正的底层异常,可以用setCause()方法将底层异常包装到高层异常中
5、,并在需要的时候用getCause()来获取。2.3 finally子句不论异常是否发生,finally中的语句都会被执行,这可以作为一种比较合适的清理资源的方式。当然如果在finally中抛出异常,则会导致try中异常类型丢失。因此建议异常的使用风格如下:try try finally catch()内层的try.finall
6、y负责清理资源,而外层的try只负责报告错误。2.4 堆栈跟踪java.lang.ThrowableThrowable(String s)Throwable(Throwable cause) Throwable(String s,Throwable cause) 用给定的cause构造一个异常Throwable getCause()void setCause()String getMessage() 获得描述信息StackTraceElement getStackTrace() 获取构造这个对象时调用堆栈的跟踪java.lang.ExceptionExcept
7、ion(Throwable cause) Exception(String s,Throwable cause) 用给定的cause构造一个异常java.lang.RuntimeExceptionRuntimeException(Throwable cause) RuntimeException(String s,Throwable cause) 用给定的cause构造一个异常java.lang.StackTraceElementString getFileName() 返回元素运行时对应的源文件名int getLineNumber()
8、返回元素运行时对应的源文件行数String getClassName() 返回元素运行时类命名String getMethodName() 返回方法名bool isnativeMethod()2.5 异常机制使用建议I 异常机制对于性能损耗较大,最好使用简单测试来避免异常发生,如在stack非空时才调用pop,比使用try包围的pop性能高100倍II 不要过分细分异常,将一段正常的流程放在一个try块中而不是分到不同的try块中,有得于代码的阅读。III 善于利用异常层次,不要只抛出RuntimeException,而应该寻找和创建更适合的子类;也不要只捕获Throwable,否则代码会较难
9、阅读。IV 合理压制异常。如果认为异常不是问题则可以合理的压制,否则则应该声明或抛出。V 早抛出,晚捕获;在程序出错的地方立即抛出异常,而尽可能向高层传递非细节异常。3 记录日志3.1 logging包的类结构3.2 全局日志日志模块,拥有一个全局变量Logger.global,可以用它向控制台输出信息。L(String s) 打印日志到标准输出Logger.global.setLevel(Level level) 设置日志级别3.3 命名日志日志也具有层次结构,不同的包可以按结构名来获取各自的日志,把记录器命名与主程序包一样的名字是一
10、个好的实践。日志有7个级别:SEVERE WARNING INFO CONFIG FINE FINER FINEST,默认为INFO级别。ALL代表所有级别,OFF表示关闭。java.util.logging.Logger类static Logger getLogger(String .log) static Logger getLogger(String name,String resName) 提供资源包的日志void setLevel(Level l) 设置日志记录器级别Level getLevel()void addHandler(Handler h)
11、160;添加处理器void removeHandler(handler h)void setUseParantHandlers(bool flag) 设置是否使用父处理器void log(Level level,String msg) 按指定级别记录日志void log(Level level,String format,Object objs) 按指定级别记录日志void logp(Level level,String classname,String methodName,String msg)void logp(Level level,String classna
12、me,String methodName,String format,Object objs)void logrb(Level level,String classname,String methodName,String resname,String format,Object objs)void throwing(String classname,String methodName,Thowable t) 记录异常的信息3.4 日志管理器配置日志系统的配置默认位于jre/lib/perties中。如果要使用不同的配置,要在JVM启动时指定,java -Djava.ut
13、il.logging.config.file = path MainClass在配置文件中可以指定日志处理器、对日志处理器进行相应的配置、日志输出级别、日志输出格式等3.5 日志的国际化在获取日志时,还可以为日志指定资源包,以支持本地化的日志显示。3.6 日志处理器默认情况下,日志将记录发送到ConsoleHandler中,并由它输出到System.err流中。日志处理器也有级别,其只处理日志条目级别高于处理器级别的条目。如果想绕过配置,则需要自己设置日志记录器的级别和处理器的级别,并将处理器安装到日志上。如果希望将日志发送到其他地方,需要添加其他的处理器。系统提供了两个有用的处理器,File
14、Handler和Sockethandler。用户可以自行继承自Handler或StreamHandler来实现自定义的日志输出方式。java.util.logging.handlerabstract void publish(LogRecord lr) 将日志写到特定流abstract void flush() 刷新已缓冲数据Formatter getFormatter()void setFormatter(Formatter f) 设置格式化器void setLevel(Level l) 设置处理级别java.util.logging.ConsoleHandlerjava.uti
15、l.logging.FileHandlerFileHandler(String namePatter,bool append) 以日志命名模式和是否追加初始化日志FileHandler(String namePatter,int limit,int count,int append) limit控制日志内最大条数,count控制循环日志数3.7 格式化器系统提供的处理器可以生成平坦文本和XML格式的日志记录,我们也可以自定义格式,只需要扩展Formatter类并覆盖format()方法即可。对于XML格式化,需要覆盖getHead/Tail来提供特定的头和尾内容。jav
16、a.util.logging.Formatterabstract String format(LogRecord lr)String getHead/Tail()String formatMessage(LogRecord lr)4 使用断言assert cond 如果cond为假,则抛出异常assert cond:expr 如果cond为假,则使用expr作字符串构造异常在默认时,断言并不生效,通过在控制台增加enable进行启用:java -enableassertion myapp或java -ea:class1 -ea:packet1启用和禁用断言并不需要重新编译程序,这是由类加载器来完成的。对于由虚拟机加载的类,可以使用esa来进行加载。断言是一种在开发和测试中使用的技术,不要将断言代替异常和日志。5 调试技术5.1 常用方法5.1.1 使用print或log方法输出
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 品牌角色设计版权使用合同(2篇)
- 七年级上册劳技全册教案
- 《HR模块知识新》课件
- 二零二五年度数字经济监事聘任与创新发展合同2篇
- 二零二五年度广告制作、发布及推广合同3篇
- 2025年沪科版八年级数学上册月考试卷含答案
- 二零二五年吊车租赁与施工材料供应合同3篇
- 2025年度租赁合同:混凝土搅拌站设备租赁协议2篇
- 2025年湘师大新版九年级历史上册阶段测试试卷
- 2025年粤人版高二地理上册阶段测试试卷
- 销售回款专项激励政策方案(地产公司)
- 生物系统建模与仿真课件
- 《威尼斯商人》阅读检测试题
- 工业门维修保养合同范本
- 风电项目核准及开工行政审批流程(备案核准、施工许可)
- 大众Polo 2016款说明书
- 公共伦理学案例分析及答案
- 四年级上册数学人教版《加乘原理》课件
- 学生版mbti职业性格测试题
- 2023年农业综合行政执法理论考试题库(含答案)
- GB/T 34766-2017矿物源总腐殖酸含量的测定
评论
0/150
提交评论