一、异常与记录日志
import java.io.PrintWriter; import java.io.StringWriter; import java.util.logging.Logger; 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 Demo6 { public static void main(String[] args) { try { throw new LoggingException(); }catch(LoggingException e) { System.err.println("Caught " + e); } } }
输出结果:
二、栈轨迹
public class Demo7 { void f1() throws Exception { throw new Exception(); } void f2()throws Exception { f1(); } void f3()throws Exception { f2(); } public static void main(String[] args) { // TODO Auto-generated method stub try { Demo7 d = new Demo7(); d.f3(); }catch(Exception e) { for(StackTraceElement s : e.getStackTrace()) { System.out.println(s); } } } }
输出结果:
结果说明:getStackTrace()此方法返回轨迹栈中的元素StackTraceElement所构成的数组,轨迹栈中的每一栈帧即为一层函数的调用。(同虚拟机栈中的栈帧)。
三、重新抛出异常
实例一:异常对象的消息内容与在那一层方法处理异常无关
public class Demo8 { void f() { try { throw new Exception("My Exception"); }catch(Exception e) { e.printStackTrace(); } } void g() { f(); } public static void main(String[] args) { // TODO Auto-generated method stub Demo8 d = new Demo8(); d.f(); } }
输出结果:
结果说明:异常对象消息内容和异常处理地点的无关性,轨迹栈的栈底永远都是main();
实例二:fillInStackTrace()重新抛出带有新消息的异常
public class Demo9 { void f() throws Exception { throw new Exception("from f()"); } //抛出原来的异常 void g() throws Exception { try { f(); }catch(Exception e) { System.out.println("g(), e.printStackTrace():"); e.printStackTrace(System.out); throw e; } } //将原来的异常填入当前调用栈消息,并覆盖原有消息 void h() throws Exception { try { f(); }catch(Exception e) { System.out.println("f(), e.printStackTrace():"); e.printStackTrace(System.out); //这里throw类似方法调用,fillInStackTrace()返回Throwable类 throw (Exception)e.fillInStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub Demo9 d = new Demo9(); try { d.g(); }catch(Exception e) { System.out.println("main() e.printStackTrace()"); e.printStackTrace(System.out); } try { d.h(); }catch(Exception e) { System.out.println("main() e.printStackTrace()"); e.printStackTrace(System.out); } } }
输出结果:
结果说明:fillInStackTrace()方法将当前异常抛出点方法调用栈的信息覆盖原来抛出点调用栈信息。
四、异常链
异常链:在捕获一个异常后抛出另外一个异常,并把原始异常的信息保存下来。
使用情形:一般在构造器中处理异常,都会另外再抛出一个异常,因为不想让调用方误以为对象被成功的建立。不过尽量不要编写抛出异常的构造器,编码会比较麻烦,应该让对象尽快安全的被初始化和建立。
实例一:
public class Demo10 { public static void main(String[] args) { // TODO Auto-generated method stub Demo10 d = new Demo10(); try { d.test(); }catch(Exception e) { e.printStackTrace(); } } void test() { try { int i = 10/0; }catch(Exception e) { throw new RuntimeException(e); } } }
输出结果:
结果说明:像这样直接使用构造器接受cause的类,只有Error、Exception、RuntimeException。其它类型需要使用initCause()方法连接。实际上,异常类的绝大部分方法都是从Throwable继承而来的。
实例二:
import java.io.IOException; class MyException extends Exception{} public class Demo11 { static void test() throws MyException{ try { throw new IOException(); }catch(Exception e) { MyException m = new MyException(); m.initCause(e); throw m; } } public static void main(String[] args) { // TODO Auto-generated method stub try { test(); }catch(Exception e) { e.printStackTrace(); } } }
输出结果:
结果说明:调用initCause()惯例,要么在创建异常的时候马上调用,要么在异常的构造器中调用。
实例三:“被检查异常”包装成“不受检查的异常”
public class Demo13 { public static void main(String[] args) { // TODO Auto-generated method stub try { test(); }catch(Exception e) { e.printStackTrace(); try { throw (Exception)e.getCause(); }catch(Exception e1) { System.out.println("getCause():"); e1.printStackTrace(); } } } static void test() { try { throw new Exception(); }catch(Exception e) { throw new RuntimeException(e); } } }
输出结果:
结果说明:getCause()方法望文知意,是用来获取Cause的,并返回Throwable类。
五、异常丢失
实例:
public class Demo12 { public static void main(String[] args) { // TODO Auto-generated method stub try { throw new RuntimeException(); }finally { return; } } }
结果说明:部分代码不会抛出任何异常,但是会有警告:finally模块没有正常编译。
六、异常的限制
1、覆盖方法时,只能够抛出基类方法异常说明里的异常。(可以是异常说明里异常的子类)这样不影响某些共用代码。
2、如果继承的或者实现的类,有同名方法,在进行覆盖时,要取throws声明的子集。
3、在进行向上转型时,用基类引用调用方法时要捕获基类此方法的异常,应为编译器根本就不清楚基类引用的实际类型,所以通不过编译。
实例:
import java.io.IOException; class A { void print() throws IOException { System.out.println("A"); throw new IOException(); } } public class Demo12 extends A{ void print() { System.out.println("Demo12"); } public static void main(String[] args) { // TODO Auto-generated method stub try { A a = new Demo12(); a.print(); }catch(Exception e) { e.printStackTrace(); } } }
输出结果:
Demo12
原文地址:https://www.cnblogs.com/mgblogs/p/11412333.html