`
seven0_0
  • 浏览: 27276 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Exception

    博客分类:
  • J2se
阅读更多

 Java异常结构:

                          

 

      Error :称为错误,由Java虚拟机生成并抛出,包括动态链接失败。虚拟机错误等,程序不对其做处理。

 

     Exception :所有异常类的父类,其子类对应了各种各样可能出现的异常事件,一般需要用户显示地声明或 

         者捕获。

 

      Runtime Exception :一类特殊的异常,如被0除。数组下标超出范围等,其产生比较频繁,处理麻烦,如果

          显示地声明或捕获将对程勋可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处

          理程序(用户可不比对其处理,不必去CATCH)。

 

Try - catch - finally:

 

try {
	throw new TestException();
		} catch (TestException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			clean();
		}
  • 必须先catch较小的异常,在catch大的
  • Finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其他部分以前,能够对程序的状态作统一的管理.
  • 无论try所指定的程序块中是否抛出列外,finally所指定的代码都要被执行
  • 通常在finally语句中可以进行资源的清除工作,如:关闭打开的文件,删除临时文件 (finally 中重新抛出另外的异常 or return ,异常会丢失)

 重新抛出异常

 重抛异常会把异常抛给上一级环境中的异常处理程序,同一个try块的后续catch子句将被忽略

此外,异常对象的所有信息多得以保留,所以printStackTrace()方法将是原来异常抛出点的调用栈的信息,而非重新抛出点的信息,要更新这个信息,调用fillINStackTrace()方法

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);
    }
    try {
      h();
    } catch(Exception e) {
      System.out.println("main: printStackTrace()");
      e.printStackTrace(System.out);
    }
  }
} /* Output:
originating the exception in f()
Inside g(),e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:7)
        at Rethrowing.g(Rethrowing.java:11)
        at Rethrowing.main(Rethrowing.java:29)
main: printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:7)
        at Rethrowing.g(Rethrowing.java:11)
        at Rethrowing.main(Rethrowing.java:29)
originating the exception in f()
Inside h(),e.printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.f(Rethrowing.java:7)
        at Rethrowing.h(Rethrowing.java:20)
        at Rethrowing.main(Rethrowing.java:35)
main: printStackTrace()
java.lang.Exception: thrown from f()
        at Rethrowing.h(Rethrowing.java:24)
        at Rethrowing.main(Rethrowing.java:35)
*///:~

  

 异常链

 

在捕获一个异常后抛出另外一个异常,并且保留原始异常的信息,

除了Error,Exception,RuntimeException,其他类型的异常要连接起来,应该使用initCause()

public Object setField(String id, Object value)
  throws DynamicFieldsException {
    if(value == null) {
      // Most exceptions don't have a "cause" constructor.
      // In these cases you must use initCause(),
      // available in all Throwable subclasses.
      DynamicFieldsException dfe =
        new DynamicFieldsException();
      dfe.initCause(new NullPointerException());
      throw dfe;
    }

  

异常的限制

 

package com.lwf.thinking.eight;
class BaseBallException extends Exception{}
class Foul extends BaseBallException{}
class Strike extends BaseBallException{}
abstract class Inning{
	public Inning() throws BaseBallException{}
		//注意构造方法抛出了异常。
	public void event() throws BaseBallException{
		//这里并没有显式throw new BaseBallException();
	}	
	public  abstract void getName() throws Foul,Strike;
	
	public  void getAge(){}
}

class StormException extends Exception{}
class RainedOut extends StormException{}
class PopFoul extends Foul{}
interface Storm{
	public void event() throws RainedOut;
	public void rainHard() throws RainedOut;
}
public class UserDefineException extends Inning implements Storm{
	public UserDefineException() throws BaseBallException,RainedOut{
		//1、因为基类的构造方法抛出了异常,根据继承机制,实例化该类必然调用基类实例化,所以该类的构造方法必须显式抛出异常
		//2、派生类的构造方法可以抛出基类所没有抛出的异常如RainedOut,注意这一点非构造方法不行。
		
	}
	public UserDefineException(String s) throws BaseBallException,PopFoul{}//只要抛出类型包含了BaseBallException即可,类国基类只抛出此类型
	
//	public void getName() throws Foul, Strike{}
		//3、派生类抛出与基类所抛出的对应异常。
//	public void getName() throws Foul{}
//	public void getName() throws Strike{}
		//4、仅抛出与基类该方法抛出异常中的任意一个
	public void getName() throws PopFoul{	}
		//5、上例中抛出了从Foul继承而来的PopFoul异常
	//	public void getName(){}
		//6、不抛出任何对应异常
//	public void getName() throws BaseBallException{}
		//7、compile error,抛出了不与基类对应的抛出异常,注意这里BaseBallException是Strike和Foul的父类也是不行的。
	
	public void event(){}
	//子类可以不抛出父类的任何异常。
   //! public void event()throw RainedOut{}
                //interface cannot add exceptions to existing methods
               // from the base class
	//注意两个基类抛出了不同的异常:这时即使用public void event() throws BaseBallException, RainedOut{}也是不行的。
	public void rainHard() throws RainedOut{}
	
	public static void main(String[] args){
		try {
			UserDefineException u = new UserDefineException();
			u.getName();
		} catch (PopFoul e){
			System.out.println("PopFoul");
		} catch (RainedOut e) {
			System.out.println("RainedOut");
		} catch (BaseBallException e) {
			System.out.println("BaseBallException");
		}
		try {
			Inning i = new UserDefineException();
			i.getName();
			//向上转型才要求捕获基类所抛出异常,如果不进行向上转型是可以不要求捕获的。
		} catch (RainedOut e) {
			System.out.println("RainedOut");
			
		} catch (Foul e) {
			System.out.println("BaseBallException");
		} catch (Strike e) {
			e.printStackTrace();
		} catch (BaseBallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
	}
}

      

 

      总结一下关于异常的限制:

  1. 对构造方法:基类构造方法抛出异常,派生类构造方法必须显式抛出对应异常(如上例第1点),且可以抛出其它异常,(如上例第2点)
                      实质上来说异常限制对构造器不起作用,即构造器可抛出任何异常,但因为派生类构造器不能捕获基类构造器抛出的异常,所以派生类所抛出异常中必须要包含基类所抛出的异常。        (http://wen66.iteye.com/blog/828820)
  2. 对普通方法:基类普通方法抛出异常,派生类普通方法可抛出对应异常(如上例第3点)、可少抛出异常(如上例第4点)、
                      可抛出对应基类异常的继承异常子类(如上例第5点)、也可不抛出异常(如上例第6点),但不能抛出与基类不对应的异常(如上例第7点)
  3. 特殊情况:  上例中的event方法,因为基类和接口都有event方法,并且抛出的异常类型又不相同,那么注意的是派生这里只有选择不抛出异常,因为
                     不管抛出哪一个或是抛出两个都是不行的。
  4. 异常说明:
       异常说明本身并不属于方法原型的一部分,所以不能根据异常说明的不同来重载方法。
        一个出现在基类异常说明中的异常,不一定会出现在派生类的异常说明中。这点与继承的规则是不同的。

project

         web.xml

	</session-config>
	<error-page>
		<exception-type>com.geenergy.pmt.exception.PMTSessionExpirationException</exception-type>
		<location>/jsp/extra/sessiontimeout.jsp</location>
	</error-page>

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics