- 浏览: 122592 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (130)
- JUnit4学习 (0)
- Spring3.X学习 (2)
- 日记 (1)
- 文学类 (2)
- Java (15)
- Thingking In Java (11)
- org.apache.poi (4)
- XML (2)
- Log4j (1)
- Jar包收集 (2)
- ExtJs (1)
- 汇编语言 (11)
- 开发工具 (0)
- 电子书 (2)
- Oracle (6)
- Ajax (1)
- Jquery (2)
- myBatis (1)
- Spring2.5学习 (6)
- Tomcat (1)
- MyEclipse (1)
- JSP (1)
- Linux shell 脚本攻略 (7)
- Python3 (2)
- HTML5 (5)
- JavaScript (7)
- Hadoop-1.2.1 (2)
- Python2.7 (12)
- Django (3)
- 软件安装 (1)
- 高级Bash脚本编程指南 (7)
- Linux命令 (3)
- Ansible (2)
- MySQL (2)
- 病历 (1)
- 操作系统 (1)
- CSS (0)
- CSS3 (0)
- 面试题 (1)
最新评论
-
hw1287789687:
http://www.cnblogs.com/hccwu/p/ ...
Java获取真实的IP地址 -
liubey:
String ip = request.getHeader(& ...
Java获取真实的IP地址 -
bewithme:
我记得uploadify这破东西只能在chrome浏览器中才有 ...
Struts2结合Jquery.uploadify上传插件的应用 -
MrLee23:
http://mrlee23.iteye.com/admin/ ...
Struts2结合Jquery.uploadify上传插件的应用 -
crysik:
import com.eshore.ppm.model.com ...
Struts2结合Jquery.uploadify上传插件的应用
2013年7月10日 星期三 00时04分21秒
第十二章 通过异常处理错误
12.1 概念
Java的基本理念是“结构不佳的代码不能运行”
Java使用异常来提供一致的错误报告模型,使得构件能够与客户端代码可靠地沟通问题。
12.2 基本异常
异常情形(Exceptional condition)是指阻止当前方法或作用域继续执行的问题。
当抛出异常后,有几件事会随之发生:
首先:同Java中其他对象一样,将使用new在堆上创建异常对象。
然后:当前的执行路径被终止,并且从当前环境中弹出对异常对象的引用。此时异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序。这个恰当的地方就是异常处理 程序。
12.2.1 异常参数
与使用Java中的其他对象一样,我们总是使用new在堆上创建异常对象,这也伴随着存储空间的分配和构造器的使用。所以标准异常类都有两个构造器:一个默认构造器,一个棘手 字符串作为参数,以便把相关信息放入异常对象的构造器:
throw new NullPointerException("t=null");
12.3 捕获异常
要明白异常是如何被捕获的,首先理解监控区域(guarded region)的概念。
12.3.1 try块
捕获异常: try{ // }
12.3.2 异常处理程序
抛出的异常必须在某处得以处理。这个“地点”就是异常处理程序。用关键字catch表示:
try{
}catch(){
}catch(){ }
终止与恢复
异常处理理论上有两种基本模型:
1) Java支持终止模型
2) 恢复模型
12.4 创建自定义异常
程序员可以自己定义异常类来表示程序中可能会遇到的特定的问题。
要自己定义异常类,必须从已有的异常类继承,最好是选择意思相近的异常类继承。
package chapter12;
/*@name PriorityQueueDemo.java
* @describe 12.4 创建自定义异常
* @since 2013-07-10 0:45
* @author 张彪
*/
class SimpleException extends Exception{}
public class InheritingException {
public void f() throws SimpleException{
System.out.println("Throw SimpleException from f();");
throw new SimpleException();
}
public static void main(String[] args) {
InheritingException sed=new InheritingException();
try {
sed.f();
} catch (SimpleException e) {
System.out.println("Caught it !");
}
}
}
/*Throw SimpleException from f();
Caught it !*/
===============================================================================
package chapter12;
class MyException extends Exception{
public MyException(){}
public MyException(String msg){super(msg);}
}
public class FullConstructors {
public static void f()throws MyException{
System.out.println("Throwing MyException from f();");
throw new MyException();
}
public static void g()throws MyException{
System.out.println("Throwing MyException from g();");
throw new MyException("Originated in g()");
}
public static void main(String[] args) {
try {
f();
} catch (MyException e) {
e.printStackTrace(System.out);
}
try {
g();
} catch (MyException e) {
e.printStackTrace(System.out);
}
}
}
/*
Throwing MyException from f();
chapter12.MyException
at chapter12.FullConstructors.f(FullConstructors.java:11)
at chapter12.FullConstructors.main(FullConstructors.java:19)
Throwing MyException from g();
chapter12.MyException: Originated in g()
at chapter12.FullConstructors.g(FullConstructors.java:15)
at chapter12.FullConstructors.main(FullConstructors.java:24)*/
在异常处理中,调用了throwable类(Exception即从此类继承)的printStackTrace()方法。它将打印“从方法调用处直到异常抛出处”的方法调用序列。
12.4.1 异常与记录日志
使用java.util.logging工具将输出记录到日志中。
package chapter12;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Logger;
/*@name LoggingException.java
* @describe 12.4.1 异常与记录日志
* @since 2013-07-10 0:59
* @author 张彪
*/
class LoggingException extends Exception{
private static Logger logger=Logger.getLogger("LoggingException");
public LoggingException(){
StringWriter trace=new StringWriter();
printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
}
public class LoggingExceptions {
public static void main(String[] args) {
try {
throw new LoggingException();
} catch (LoggingException e) {
System.out.println("Caught"+e);
}
try {
throw new LoggingException();
} catch (LoggingException e) {
System.out.println("Caught"+e);
}
}
}
/*2013-7-10 1:07:56 chapter12.LoggingException <init>
严重: chapter12.LoggingException
at chapter12.LoggingExceptions.main(LoggingExceptions.java:23)
Caughtchapter12.LoggingException
Caughtchapter12.LoggingException
2013-7-10 1:07:56 chapter12.LoggingException <init>
严重: chapter12.LoggingException
at chapter12.LoggingExceptions.main(LoggingExceptions.java:28)*/
这个Logging对象会将其输出发送到System.err。 为了产生日志记录消息,我们欲获取异常抛出处的栈轨迹。
更常见的情况是我们需要捕获和记录其他人编写的异常,异常我们必须在异常处理程序中生成日志消息。
package chapter12;
class MyException2 extends Exception{
private int x;
public MyException2(){}
public MyException2(String msg){super(msg);}
public MyException2(String msg,int x){
super(msg);
this.x=x;
}
public int val(){
return x;
}
public String getMessage(){
return "Detail Message:"+x+ " "+super.getMessage();
}
}
public class ExtraFeatures{
public static void f() throws MyException2{
System.out.println("Throwing MyException2 from f()");
throw new MyException2();
}
public static void g() throws MyException2{
System.out.println("Throwing MyException2 from g()");
throw new MyException2("Originated in g()");
}
public static void h() throws MyException2{
System.out.println("Throwing MyException2 from h()");
throw new MyException2("Originated in g()",47);
}
public static void main(String[] args) {
try {
f();
} catch (MyException2 e) {
e.printStackTrace(System.out);
}
try {
g();
} catch (MyException2 e) {
e.printStackTrace(System.out);
}
try {
h();
} catch (MyException2 e) {
e.printStackTrace(System.out);
}
}
}
12.5 异常说明
Java鼓励热门把方法可能抛出的异常告知使用此方法的客户端程序员。这是种优雅的做法。异常说明属于方法说明的一部分。紧跟在形式参数的列表后面。
异常说明使用了附加的关键字throws,后面接一个所有潜在异常类型的列表,所以方法定义可能如下:
void f() throws TooBig, TooSmall, DivZero{ // .....}
12.6 捕获所有异常
可以通过异常基类Exception来捕获异常处理程序中所有的异常。
下面展示Exception的用法:
package chapter12;
public class ExceptionMethods{
public static void main(String[] args) {
try {
throw new Exception("My Exception");
} catch (Exception e) {
System.out.println("Caught Exception");
System.out.println("e.getMessage()="+e.getMessage());
System.out.println("e.getLocalizedMessage()="+e.getLocalizedMessage());
System.out.println("toString()"+e);
System.out.println("printStackTrace()");
e.printStackTrace(System.out);
}
}
}
12.6.1 栈轨迹
printStackTrace()方法所提供的信息可以通过getStackTrace()方法直接访问。这个方法将返回一个由栈轨迹中的元素所构成的数组,其中每一个元素都表示栈中的一帧。
下面是简单演示:
package chapter12.exceptions;
/*@name WhoCalled.java
* @describe 12.6.1 栈轨迹
* @since 2013-07-13 02:45
* @author 张彪
*/
public class WhoCalled {
static void f(){
try {
throw new Exception();
} catch (Exception e) {
for(StackTraceElement t: e.getStackTrace()){
System.out.println(t.getMethodName());
}
}
}
static void g(){f();}
static void h(){g();}
public static void main(String[] args) {
f();
System.out.println("-------------------");
g();
System.out.println("-------------------");
h();
}
}
/*f
main
-------------------
f
g
main
-------------------
f
g
h
main*/
元素0是栈顶元素,并且是调用序列中的最后一个方法调用。数组中的最后一个元素和栈底是调用序列中的第一个方法调用。
12.6.2 重新抛出异常
有时候希望把刚捕获的异常重新抛出。如下:
catch (Exception e)
{
System.out.println("An exception was thrown");
throw e;
}
如下例子:
package chapter12.exceptions;
/*@name WhoCalled.java
* @describe 12.6.2 重新抛出异常
* @since 2013-07-13 03:09
* @author 张彪
*/
public class ReThrowing {
public static void f() throws Exception{
System.out.println("originating the exception in f()");
throw new Exception("thrown from f()");
}
public static void g() throws Exception{
try {
f();
} catch (Exception e) {
System.out.println("Inside g(),e.printStackTrace()");
e.printStackTrace(System.out);
throw e;
}
}
public static void h() throws Exception{
try {
f();
} catch (Exception e) {
System.out.println("Inside h(),e.printStackTrace()");
e.printStackTrace(System.out);
throw (Exception)e.fillInStackTrace();
}
}
public static void main(String[] args) {
try {
g();
} catch (Exception e) {
System.out.println("main:printStackTrace()");
e.printStackTrace(System.out);
}
System.out.println("---------");
try {
h();
} catch (Exception e) {
System.out.println("main:printStackTrace()");
e.printStackTrace(System.out);
}
}
}
调用fillInStackTrace()的那一行就成了异常的新发生地了。即原来的异常发生点信息丢失了,剩下的是与新的抛出点有关的信息。
永远不必为清理一个异常而担心,他们都是用New在堆上创建的对象,所以垃圾回收器会自动把他们清理掉。
12.6.3 异常链
12.7 Java标准异常
Throwable这个Java类被用来表示任何可以作为异常被抛出的类。 分为Error 和Exception。
12.7.1 RunException
运行时异常会自动被Java虚拟机抛出
如果RunException没有被捕获而直达main()方法,那么在程序退出前将调用异常的printStackTrace()方法。
12.8 使用finally进行清理
如果希望无论try块中的异常是否抛出,它们都能得到执行,那么可以在异常处理程序后面加上finally子句。
try{}
catch(){}
finaly{}
可以将try块放在循环中,这样就建立了一个“程序继续执行之前必须要达到”的条件。
12.8.1 finally用来做什么
当要把除内存之外的资源恢复到它们的初始状态时,就要用到finally子句。
12.8.2 在return中使用finally
package chapter12.exceptions;
/*@name MultipleReturn.java
* @describe 12.8.2 在return中使用finally
* @since 2013-07-28 10:27
* @author 张彪
*/
public class MultipleReturn {
public static void f(int i){
System.out.println("Initialization that requires cleanup");
try {
System.out.println("Point 1");
if(i==1) return;
System.out.println("Point 2");
if(i==2) return;
System.out.println("Point 3");
if(i==3) return;
System.out.println("Point 4");
if(i==4) return;
} finally {
System.out.println("Performing cleanup");
}
}
public static void main(String[] args) {
for (int i = 1; i < 4; i++) {
MultipleReturn.f(i);
}
}
}
/*Initialization that requires cleanup
Point 1
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Point 3
Performing cleanup*/
可以发现finally中的方法会在return之前被执行。
12.8.3 缺憾:异常丢失
用某些特殊方法使用finally子句时,有些异常可以轻易的被忽略掉。
package chapter12.exceptions;
class VeryImportantExcepton extends Exception{
public String toString(){
return "A very impotant exception";
}
}
class HoHumException extends Exception{
public String toString(){
return "A trivial exception";
}
}
public class LostMessage {
void f() throws VeryImportantExcepton{
throw new VeryImportantExcepton();
}
void dispose() throws HoHumException{
throw new HoHumException();
}
public static void main(String[] args) {
try{
LostMessage ls=new LostMessage();
try{
ls.f();
}finally{
ls.dispose();
}
}catch (Exception e) {
System.out.println(e);
}
}
}
/*A trivial exception*/
从打印出的信息可以看出VeryImportantExcepton不见了。
一种更加简单丢失异常的方式是从finally中返回:
public class Exceptionilencer {
public static void main(String[] args) {
try {
throw new RuntimeException();
} finally{
//using 'return' inside the finally block will slience any thrown exception
return;
}
}
}
12.9 异常限制
当覆盖方法的时候,只能抛出在基类方法的异常说明里列出的那些异常。
12.10 构造器
如果构造器内抛出了异常,这些清理行为也许就不能正常工作了。这意味着写构造器时要格外细心。
package chapter12.exceptions;
/*@name CleanupIdioom.java
* @describe 12.10 构造器 ,注意构造器时异常的处理
* @since 2013-08-01 20:15
* @author 张彪
*/
class NeedCleanup{
private static long counter=1;
private final long id=counter++;
public void dispose(){
System.out.println("NeedCleanup "+id+" dispose");
}
}
class ConstructionException extends Exception{}
class NeedCleanup2 extends NeedCleanup{
public NeedCleanup2() throws ConstructionException{}
}
public class CleanupIdioom {
public static void main(String[] args) {
NeedCleanup nc1=new NeedCleanup();
try {
}finally {
nc1.dispose();
}
//select2
NeedCleanup nc2=new NeedCleanup();
NeedCleanup nc3=new NeedCleanup();
try{
}finally{
nc3.dispose();
nc2.dispose();
}
//select3
try {
NeedCleanup2 nc4= new NeedCleanup2();
try {
NeedCleanup2 nc5= new NeedCleanup2();
} finally{
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
12.11 异常匹配
抛出异常时,异常处理系统会按照代码的书写顺序找出“最近”的处理程序。找到后,将不再继续查找。
派生类的对象也可以匹配其基类的处理程序。
package chapter12.exceptions;
class Annoyance extends Exception{}
class Sneeze extends Annoyance{}
public class Human {
public static void main(String[] args) {
try {
throw new Sneeze();
} catch (Sneeze s) {
System.out.println("Caught Sneeze");
}catch (Annoyance a) {
System.out.println("Caught Annoyance1");
}
try {
throw new Sneeze();
} catch (Annoyance e) {
System.out.println("Caught Annoyance2");
}
}
}
/*Caught Sneeze
Caught Annoyance2*/
//如果把捕获基类的catch子句放在最前面,依次想把派生类的异常给“屏蔽”掉,就像这样:
try {
throw new Sneeze();
} catch (Annoyance s) {
System.out.println("Caught Sneeze");
}catch (Sneeze a) {
System.out.println("Caught Annoyance1");
}
}
这样编译器会发现Sneeze的catch子句永远也得不到执行,因此它会向你报告错误。
12.12 其它可选方式
事实上,异常处理的一个重要目标是将错误处理的代码和错误发生的地点相分离。
“被检查的异常”及其并发症,以及采用什么方法解决该问题。
12.12.1 历史
12.12.2 观点
12.12.3 把异常传递给控制台
12.12.4 把“被检查的异常”转换为“不检查的异常”
12.13 异常使用指南
12.14 总结
2013-08-01 21:02 记 @jinrongdajie31.xichengqu.beijing
是的! 本人初学,谢谢指点!
第十二章 通过异常处理错误
12.1 概念
Java的基本理念是“结构不佳的代码不能运行”
Java使用异常来提供一致的错误报告模型,使得构件能够与客户端代码可靠地沟通问题。
12.2 基本异常
异常情形(Exceptional condition)是指阻止当前方法或作用域继续执行的问题。
当抛出异常后,有几件事会随之发生:
首先:同Java中其他对象一样,将使用new在堆上创建异常对象。
然后:当前的执行路径被终止,并且从当前环境中弹出对异常对象的引用。此时异常处理机制接管程序,并开始寻找一个恰当的地方来继续执行程序。这个恰当的地方就是异常处理 程序。
12.2.1 异常参数
与使用Java中的其他对象一样,我们总是使用new在堆上创建异常对象,这也伴随着存储空间的分配和构造器的使用。所以标准异常类都有两个构造器:一个默认构造器,一个棘手 字符串作为参数,以便把相关信息放入异常对象的构造器:
throw new NullPointerException("t=null");
12.3 捕获异常
要明白异常是如何被捕获的,首先理解监控区域(guarded region)的概念。
12.3.1 try块
捕获异常: try{ // }
12.3.2 异常处理程序
抛出的异常必须在某处得以处理。这个“地点”就是异常处理程序。用关键字catch表示:
try{
}catch(){
}catch(){ }
终止与恢复
异常处理理论上有两种基本模型:
1) Java支持终止模型
2) 恢复模型
12.4 创建自定义异常
程序员可以自己定义异常类来表示程序中可能会遇到的特定的问题。
要自己定义异常类,必须从已有的异常类继承,最好是选择意思相近的异常类继承。
package chapter12;
/*@name PriorityQueueDemo.java
* @describe 12.4 创建自定义异常
* @since 2013-07-10 0:45
* @author 张彪
*/
class SimpleException extends Exception{}
public class InheritingException {
public void f() throws SimpleException{
System.out.println("Throw SimpleException from f();");
throw new SimpleException();
}
public static void main(String[] args) {
InheritingException sed=new InheritingException();
try {
sed.f();
} catch (SimpleException e) {
System.out.println("Caught it !");
}
}
}
/*Throw SimpleException from f();
Caught it !*/
===============================================================================
package chapter12;
class MyException extends Exception{
public MyException(){}
public MyException(String msg){super(msg);}
}
public class FullConstructors {
public static void f()throws MyException{
System.out.println("Throwing MyException from f();");
throw new MyException();
}
public static void g()throws MyException{
System.out.println("Throwing MyException from g();");
throw new MyException("Originated in g()");
}
public static void main(String[] args) {
try {
f();
} catch (MyException e) {
e.printStackTrace(System.out);
}
try {
g();
} catch (MyException e) {
e.printStackTrace(System.out);
}
}
}
/*
Throwing MyException from f();
chapter12.MyException
at chapter12.FullConstructors.f(FullConstructors.java:11)
at chapter12.FullConstructors.main(FullConstructors.java:19)
Throwing MyException from g();
chapter12.MyException: Originated in g()
at chapter12.FullConstructors.g(FullConstructors.java:15)
at chapter12.FullConstructors.main(FullConstructors.java:24)*/
在异常处理中,调用了throwable类(Exception即从此类继承)的printStackTrace()方法。它将打印“从方法调用处直到异常抛出处”的方法调用序列。
12.4.1 异常与记录日志
使用java.util.logging工具将输出记录到日志中。
package chapter12;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Logger;
/*@name LoggingException.java
* @describe 12.4.1 异常与记录日志
* @since 2013-07-10 0:59
* @author 张彪
*/
class LoggingException extends Exception{
private static Logger logger=Logger.getLogger("LoggingException");
public LoggingException(){
StringWriter trace=new StringWriter();
printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
}
public class LoggingExceptions {
public static void main(String[] args) {
try {
throw new LoggingException();
} catch (LoggingException e) {
System.out.println("Caught"+e);
}
try {
throw new LoggingException();
} catch (LoggingException e) {
System.out.println("Caught"+e);
}
}
}
/*2013-7-10 1:07:56 chapter12.LoggingException <init>
严重: chapter12.LoggingException
at chapter12.LoggingExceptions.main(LoggingExceptions.java:23)
Caughtchapter12.LoggingException
Caughtchapter12.LoggingException
2013-7-10 1:07:56 chapter12.LoggingException <init>
严重: chapter12.LoggingException
at chapter12.LoggingExceptions.main(LoggingExceptions.java:28)*/
这个Logging对象会将其输出发送到System.err。 为了产生日志记录消息,我们欲获取异常抛出处的栈轨迹。
更常见的情况是我们需要捕获和记录其他人编写的异常,异常我们必须在异常处理程序中生成日志消息。
package chapter12;
class MyException2 extends Exception{
private int x;
public MyException2(){}
public MyException2(String msg){super(msg);}
public MyException2(String msg,int x){
super(msg);
this.x=x;
}
public int val(){
return x;
}
public String getMessage(){
return "Detail Message:"+x+ " "+super.getMessage();
}
}
public class ExtraFeatures{
public static void f() throws MyException2{
System.out.println("Throwing MyException2 from f()");
throw new MyException2();
}
public static void g() throws MyException2{
System.out.println("Throwing MyException2 from g()");
throw new MyException2("Originated in g()");
}
public static void h() throws MyException2{
System.out.println("Throwing MyException2 from h()");
throw new MyException2("Originated in g()",47);
}
public static void main(String[] args) {
try {
f();
} catch (MyException2 e) {
e.printStackTrace(System.out);
}
try {
g();
} catch (MyException2 e) {
e.printStackTrace(System.out);
}
try {
h();
} catch (MyException2 e) {
e.printStackTrace(System.out);
}
}
}
12.5 异常说明
Java鼓励热门把方法可能抛出的异常告知使用此方法的客户端程序员。这是种优雅的做法。异常说明属于方法说明的一部分。紧跟在形式参数的列表后面。
异常说明使用了附加的关键字throws,后面接一个所有潜在异常类型的列表,所以方法定义可能如下:
void f() throws TooBig, TooSmall, DivZero{ // .....}
12.6 捕获所有异常
可以通过异常基类Exception来捕获异常处理程序中所有的异常。
下面展示Exception的用法:
package chapter12;
public class ExceptionMethods{
public static void main(String[] args) {
try {
throw new Exception("My Exception");
} catch (Exception e) {
System.out.println("Caught Exception");
System.out.println("e.getMessage()="+e.getMessage());
System.out.println("e.getLocalizedMessage()="+e.getLocalizedMessage());
System.out.println("toString()"+e);
System.out.println("printStackTrace()");
e.printStackTrace(System.out);
}
}
}
12.6.1 栈轨迹
printStackTrace()方法所提供的信息可以通过getStackTrace()方法直接访问。这个方法将返回一个由栈轨迹中的元素所构成的数组,其中每一个元素都表示栈中的一帧。
下面是简单演示:
package chapter12.exceptions;
/*@name WhoCalled.java
* @describe 12.6.1 栈轨迹
* @since 2013-07-13 02:45
* @author 张彪
*/
public class WhoCalled {
static void f(){
try {
throw new Exception();
} catch (Exception e) {
for(StackTraceElement t: e.getStackTrace()){
System.out.println(t.getMethodName());
}
}
}
static void g(){f();}
static void h(){g();}
public static void main(String[] args) {
f();
System.out.println("-------------------");
g();
System.out.println("-------------------");
h();
}
}
/*f
main
-------------------
f
g
main
-------------------
f
g
h
main*/
元素0是栈顶元素,并且是调用序列中的最后一个方法调用。数组中的最后一个元素和栈底是调用序列中的第一个方法调用。
12.6.2 重新抛出异常
有时候希望把刚捕获的异常重新抛出。如下:
catch (Exception e)
{
System.out.println("An exception was thrown");
throw e;
}
如下例子:
package chapter12.exceptions;
/*@name WhoCalled.java
* @describe 12.6.2 重新抛出异常
* @since 2013-07-13 03:09
* @author 张彪
*/
public class ReThrowing {
public static void f() throws Exception{
System.out.println("originating the exception in f()");
throw new Exception("thrown from f()");
}
public static void g() throws Exception{
try {
f();
} catch (Exception e) {
System.out.println("Inside g(),e.printStackTrace()");
e.printStackTrace(System.out);
throw e;
}
}
public static void h() throws Exception{
try {
f();
} catch (Exception e) {
System.out.println("Inside h(),e.printStackTrace()");
e.printStackTrace(System.out);
throw (Exception)e.fillInStackTrace();
}
}
public static void main(String[] args) {
try {
g();
} catch (Exception e) {
System.out.println("main:printStackTrace()");
e.printStackTrace(System.out);
}
System.out.println("---------");
try {
h();
} catch (Exception e) {
System.out.println("main:printStackTrace()");
e.printStackTrace(System.out);
}
}
}
调用fillInStackTrace()的那一行就成了异常的新发生地了。即原来的异常发生点信息丢失了,剩下的是与新的抛出点有关的信息。
永远不必为清理一个异常而担心,他们都是用New在堆上创建的对象,所以垃圾回收器会自动把他们清理掉。
12.6.3 异常链
12.7 Java标准异常
Throwable这个Java类被用来表示任何可以作为异常被抛出的类。 分为Error 和Exception。
12.7.1 RunException
运行时异常会自动被Java虚拟机抛出
如果RunException没有被捕获而直达main()方法,那么在程序退出前将调用异常的printStackTrace()方法。
12.8 使用finally进行清理
如果希望无论try块中的异常是否抛出,它们都能得到执行,那么可以在异常处理程序后面加上finally子句。
try{}
catch(){}
finaly{}
可以将try块放在循环中,这样就建立了一个“程序继续执行之前必须要达到”的条件。
12.8.1 finally用来做什么
当要把除内存之外的资源恢复到它们的初始状态时,就要用到finally子句。
12.8.2 在return中使用finally
package chapter12.exceptions;
/*@name MultipleReturn.java
* @describe 12.8.2 在return中使用finally
* @since 2013-07-28 10:27
* @author 张彪
*/
public class MultipleReturn {
public static void f(int i){
System.out.println("Initialization that requires cleanup");
try {
System.out.println("Point 1");
if(i==1) return;
System.out.println("Point 2");
if(i==2) return;
System.out.println("Point 3");
if(i==3) return;
System.out.println("Point 4");
if(i==4) return;
} finally {
System.out.println("Performing cleanup");
}
}
public static void main(String[] args) {
for (int i = 1; i < 4; i++) {
MultipleReturn.f(i);
}
}
}
/*Initialization that requires cleanup
Point 1
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Performing cleanup
Initialization that requires cleanup
Point 1
Point 2
Point 3
Performing cleanup*/
可以发现finally中的方法会在return之前被执行。
12.8.3 缺憾:异常丢失
用某些特殊方法使用finally子句时,有些异常可以轻易的被忽略掉。
package chapter12.exceptions;
class VeryImportantExcepton extends Exception{
public String toString(){
return "A very impotant exception";
}
}
class HoHumException extends Exception{
public String toString(){
return "A trivial exception";
}
}
public class LostMessage {
void f() throws VeryImportantExcepton{
throw new VeryImportantExcepton();
}
void dispose() throws HoHumException{
throw new HoHumException();
}
public static void main(String[] args) {
try{
LostMessage ls=new LostMessage();
try{
ls.f();
}finally{
ls.dispose();
}
}catch (Exception e) {
System.out.println(e);
}
}
}
/*A trivial exception*/
从打印出的信息可以看出VeryImportantExcepton不见了。
一种更加简单丢失异常的方式是从finally中返回:
public class Exceptionilencer {
public static void main(String[] args) {
try {
throw new RuntimeException();
} finally{
//using 'return' inside the finally block will slience any thrown exception
return;
}
}
}
12.9 异常限制
当覆盖方法的时候,只能抛出在基类方法的异常说明里列出的那些异常。
12.10 构造器
如果构造器内抛出了异常,这些清理行为也许就不能正常工作了。这意味着写构造器时要格外细心。
package chapter12.exceptions;
/*@name CleanupIdioom.java
* @describe 12.10 构造器 ,注意构造器时异常的处理
* @since 2013-08-01 20:15
* @author 张彪
*/
class NeedCleanup{
private static long counter=1;
private final long id=counter++;
public void dispose(){
System.out.println("NeedCleanup "+id+" dispose");
}
}
class ConstructionException extends Exception{}
class NeedCleanup2 extends NeedCleanup{
public NeedCleanup2() throws ConstructionException{}
}
public class CleanupIdioom {
public static void main(String[] args) {
NeedCleanup nc1=new NeedCleanup();
try {
}finally {
nc1.dispose();
}
//select2
NeedCleanup nc2=new NeedCleanup();
NeedCleanup nc3=new NeedCleanup();
try{
}finally{
nc3.dispose();
nc2.dispose();
}
//select3
try {
NeedCleanup2 nc4= new NeedCleanup2();
try {
NeedCleanup2 nc5= new NeedCleanup2();
} finally{
}
} catch (Exception e) {
// TODO: handle exception
}
}
}
12.11 异常匹配
抛出异常时,异常处理系统会按照代码的书写顺序找出“最近”的处理程序。找到后,将不再继续查找。
派生类的对象也可以匹配其基类的处理程序。
package chapter12.exceptions;
class Annoyance extends Exception{}
class Sneeze extends Annoyance{}
public class Human {
public static void main(String[] args) {
try {
throw new Sneeze();
} catch (Sneeze s) {
System.out.println("Caught Sneeze");
}catch (Annoyance a) {
System.out.println("Caught Annoyance1");
}
try {
throw new Sneeze();
} catch (Annoyance e) {
System.out.println("Caught Annoyance2");
}
}
}
/*Caught Sneeze
Caught Annoyance2*/
//如果把捕获基类的catch子句放在最前面,依次想把派生类的异常给“屏蔽”掉,就像这样:
try {
throw new Sneeze();
} catch (Annoyance s) {
System.out.println("Caught Sneeze");
}catch (Sneeze a) {
System.out.println("Caught Annoyance1");
}
}
这样编译器会发现Sneeze的catch子句永远也得不到执行,因此它会向你报告错误。
12.12 其它可选方式
事实上,异常处理的一个重要目标是将错误处理的代码和错误发生的地点相分离。
“被检查的异常”及其并发症,以及采用什么方法解决该问题。
12.12.1 历史
12.12.2 观点
12.12.3 把异常传递给控制台
12.12.4 把“被检查的异常”转换为“不检查的异常”
12.13 异常使用指南
12.14 总结
2013-08-01 21:02 记 @jinrongdajie31.xichengqu.beijing
- chapter12.rar (6.7 KB)
- 下载次数: 0
评论
2 楼
listen-raining
2013-08-20
freezingsky 写道
异常虽好,但永远不要想着用异常来控制流程。应该把这句话加上去。
是的! 本人初学,谢谢指点!
1 楼
freezingsky
2013-08-01
异常虽好,但永远不要想着用异常来控制流程。应该把这句话加上去。
发表评论
-
第十三章 字符串
2013-08-06 00:50 9382013年8月1日 星期四 21时05分59秒 第十三章 字 ... -
第十一章 持有对象
2013-07-09 00:49 9562013年6月24日 星期一 20时57分09秒 第十一章 ... -
第十四章 类型信息
2013-07-02 01:26 9562013年6月25日 星期二 23时12分42秒 第十四章 ... -
第十章 内部类
2013-06-24 20:47 10172013年6月23日 星期日 16时50分56秒 第十章 内 ... -
第九章 接口
2013-06-23 16:46 8782013年6月20日 星期四 21时41分40秒 第九章 接 ... -
第八章 多态
2013-06-19 23:06 7052013年6月17日 星期一 23 ... -
Thinking in Java Fourth Edition Source Code
2013-06-17 23:10 526Thinking in Java F ... -
第七章 复用类
2013-06-17 22:36 5932013年6月16日 星期日 21时06分54秒 第七章 复 ... -
第六章 访问权限控制
2013-06-16 21:05 8882013年6月16日 星期日 11时10分46秒 第六章 访 ... -
第五章 初始化与清理
2013-06-16 10:58 6332013年6月15日 星期六 16 ...
相关推荐
Java编程思想第十二章通过异常处理错误.pptx
本课件的第12章主要关注如何处理这些异常以及如何进行程序调试,以确保代码能够正确执行。 异常处理在Python中通过使用`try-except`语句来实现。当`try`块中的代码出现异常时,程序会立即跳转到相应的`except`块中...
根据提供的信息,我们可以总结出以下关于《Java语言程序设计基础第十版》第十二章的一些关键知识点及解答: ### 一、异常处理基本概念 #### 12.1 **问题:** 异常处理的主要思想是什么? **解答:** 异常处理的主要...
C#入门ppt,一共16章
总之,《数据挖掘:概念与技术》(第三版)第12章深入介绍了异常处理的相关理论和技术,并提供了丰富的案例研究。通过对异常处理的学习,可以更好地理解如何从复杂多变的数据集中发现有价值的信息,这对于提高数据...
在Python中,文件存取是编程中常见的操作,它涉及文件的读取、写入以及异常处理。本章主要讲解了如何使用Python进行文件操作。 1. **文件读取** - 使用`open()`函数打开文件,例如`open('work\readme.txt')`。在...
**SpringMVC框架中的异常处理**是Java开发中不可或缺的一部分,它确保了应用程序在遇到错误时能够优雅地处理并提供有用的反馈。在SpringMVC框架中,异常处理机制允许开发者集中处理可能出现的各种异常,提高代码的可...
#### 第 12 章 通过异常处理错误 第十二章讲解了Java中的异常处理机制。异常处理是处理程序运行时错误的有效方式。本章首先介绍了异常的概念,然后详细讨论了如何使用try-catch-finally语句来捕获和处理异常,以及...
由于上传文件大小限制...第12章 通过异常处理错误 第13章 字符串 第14章 类型信息 第15章 泛型 第16章 数组 第17章 容器深入研究 第18章 Java I/O系统 第19章 枚举类型 第20章 注解 第21章 并发 第22章 图形化用户界面
非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 第7章 复用类 第8章 多态 第9章 接口 第10章 内部类 第11章 持有对象 第12章 通过异常处理错误 第13章 字符串 第...
通过解决这些习题,学生可以加深对C++语言特性的理解,包括类和对象、动态内存管理、模板、异常处理、标准模板库(STL)等。 在实际使用这些习题答案时,建议读者首先尝试独立完成习题,遇到问题后再参照答案进行核对...
在Java编程中,异常处理...通过正确使用异常处理,开发者可以更有效地定位和解决程序中的错误,提高程序的稳定性和用户体验。同时,自定义异常允许开发者根据项目需求创建特定的异常类型,使代码更具可读性和可维护性。
《JSP程序开发范例宝典》第十二章聚焦于JSP(Java Server Pages)的高级应用和实战技巧。在这一章中,我们通常会深入探讨以下关键知识点: 1. **自定义标签库(Custom Tags)**:JSP 2.0引入了自定义标签库的概念,...
第十二章 错误异常和错误处理 第十三章 浮点运算 第十四章 调试和跟踪测试 第十五章 Keil ARM 微控制器开发套件入门 第十六章 IAR Embedded Workbench for ARM 入门 第十七章 GCC 入门 第十八章 输入和输出软件实例 ...
《Java开发实战经典》是许多Java初学者的重要学习资料,其第十二章涵盖了诸多关键知识点。这章可能涉及了面向对象编程的深入理解、异常处理、集合框架的使用、多线程、网络编程或者IO流等内容。课后习题通常用于巩固...
在北大青鸟S1JAVA课程的第十二章中,学员们会接触到一系列深入的Java编程概念和实践。这一章节的课后练习旨在巩固所学知识,提升编程技能。以下是本章涉及的一些关键知识点: 1. **面向对象编程基础**:在Java中,...
本章主要介绍了Java中的异常处理机制及其重要性。 异常是程序运行时遇到的问题,如文件错误、设备故障、逻辑错误等。Java提供了一套完整的异常处理框架,使得开发者可以有效地管理和响应这些异常情况。异常处理的...
异常处理是Java编程中的一个重要概念,它允许程序员在程序运行过程中处理错误情况,避免程序崩溃。 - **基本语法**: ```java try { // 可能抛出异常的代码 } catch (ExceptionType1 e1) { // 处理异常 } ...