zoukankan      html  css  js  c++  java
  • java异常处理Exception

           我看别人的面经中有一道题目就问到了Exception,即java的异常处理的,我曾经也学了java的异常处理,可是我查了下,看了别人的博客关于写的exception异常处理。我发现,自己学的不坚固,仅仅学到了一点皮毛而已,在看了那么多博客和资料后。我做下总结吧,不然我大脑都混乱了。

          java的中异常祖先是Throwable,Throwable的直接子类是Exception和Error。

          Error通过单词我们就知道,是错误的意思。这样的错误通常是jvm执行产生的错误,出现这样的错误,我们的程序不能解决,比方内存溢出oom,堆溢出等。这样的错误。我们不必处理,直接让jvm抛出报错,我们没办法解决就无论了。

         Exception中文意思是异常,那么Exception又分为检查性异常和非检查性异常。比方RuntimeException类及子类就是非检查性异处,表示执行时出现的异常,有数组越界,空指针异常。我们也能够不进行处理,让jvm自己抛出异常,当然假设我们能够预见这样的异常的话。最好在程序中进行推断检查,程序写健壮些。有的这样的异常就能够避免了。effect java有这样的处理的推荐,详细的能够看看这本书。

        Exception另一类是检查性异常,这是除RuntimeException类及子类外的Exception类和Exception类的其它子类。

    检查性异常,必需要进行异常处理的或者抛出,否则编译器会报错。

          

       异常处理一般用到以下几个keywordtry,catch。finally。throws,throw,以下我逐个做一个说明。

        try:

        对于可能会抛出异常的代码一般放在try{}代码块中,比方:

     

    try {
      int   i=2/0;
    			t.test1();
    			//System.out.println("kkk"+st);
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			System.out.println("i will catch you....");
    			e.printStackTrace();
    		}


    上面的代码2/0,肯定会抛出异常的。所以须要放在try{}块中,在try块中。假设哪一行抛出了异常,那么try块后面的代码将不再运行,将直接进入异常处理代码块。


      catch:

        catch(Excetion e){}这样的结构是用来处理。try代码块中抛出的异常的,能够有非常多的catch代码块,只是要注意的是,当有非常多catch代码块,而且catch里面的參数有父子关系的时候,catch里面的參数一定要是子类在前面,父类在后面。由于按catch代码块出现的先后顺序匹配抛出的异常,一旦抛出的异常是哪个catch里面參数的子类或同类,那么就能够被这个catch代码块进行处理。那么其它的catch代码块就算也符合这样的条件也不在进行处理了,假设有finally代码块的话就直接进入finally代码块中,没得则直接执行catch代码块后面的代码了。


        finally:

        finally代码块是异常处理中一定会运行的代码块,就算没得异常也会运行。有异常则进入catch代码块中处理后,在进入finally中处理。

        在这里要注意一点,假如在try代码块中有return 语句。那么也是先运行finally里面的代码块后在运行return语句的。

     还需注意一点的是。函数的返回值,是最后活动栈的栈顶的值。假设try进行return了,那么在finally中我也进行return。那么finally代码块里面的return的值在栈顶,所以会返回finally中return的值。有例如以下測试代码。

    package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException(){
    		try{
    			return "I am in try";
    		}finally{
    			return "I am in finally";
    		}
    	}
    	
    	
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    
    		TestException3 te=new TestException3();
    		System.out.println(te.testException());
    	}
    
    }
    


    执行结果是:

       I am in finally


    注意我这里是測试所以在finally中进行return了,一般不推荐在finally中进行return。



        throws:

        throws的使用方法是在      函数名(參数1,參数2.....)throws 异常类1,异常类2,异常类3.....{}

       throws是表明这个函数可能会有异常产生,可是函数不进行异常处理,函数将向上抛异常,把异常处理交给函数的调用处进行处理。假设调用处。不进行处理则能够在进行向上抛。。

    直到有地方进行try{}catch(){}异常处理,或者最后抛给jvm(不建议这么使用)。

    package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException() throws Exception{
    		/*try{
    			return "I am in try";
    		}finally{
    			return "I am in finally";
    		}*/
    		System.out.println("我不进行异常处理。我将异常向上抛。throws");
    		int i=2/0;
    		System.out.println("有异常我将得不到运行。。。。");
    		return "我是使用throws抛的异常";
    	}
    	
    	
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    
    		TestException3 te=new TestException3();
    		try {
    			System.out.println(te.testException());
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    
    }
    


    输出结果:

    <span style="font-size:18px;">我不进行异常处理。我将异常向上抛,throws
    java.lang.ArithmeticException: / by zero
    	at com.wj.exception.TestException3.testException(TestException3.java:13)
    	at com.wj.exception.TestException3.main(TestException3.java:24)
    </span>



           throw:

         throw的作用是详细的抛出一个异常类对象。一般在方法里面使用。当在try代码块中使用的时候。直接进入catch代码块中进行处理。

    比方:

    package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException(){
    		try{
    			throw new Exception("i is throw exception");
    		}catch(Exception e){
    			System.out.println("我处理throw抛出的异常");
    		}finally{
    			System.out.println("我运行finally代码块
    ");
    			
    		}
    		System.out.println("异常处理结束!

    !"); return "I am in finally"; } public static void main(String[] args) { // TODO Auto-generated method stub TestException3 te=new TestException3(); System.out.println(te.testException()); } }



    同意结果:

    我处理throw抛出的异常
    我运行finally代码块


    异常处理结束!!


    I am in finally



            throw手动抛出的异常须要从里到到外查找处理的try代码块。没有处理话,就须要把方法后面加throws,把异常向上抛。看例如以下代码:


        1

    package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException(){
    		try{
    			int i=3/0;
    		}catch(Exception e){
    			throw new Exception();
    		}finally{
    			System.out.println("我运行finally代码块
    ");
    			
    		}
    		//System.out.println("异常处理结束。。!

    "); return "I am in finally"; } public static void main(String[] args) { // TODO Auto-generated method stub TestException3 te=new TestException3(); System.out.println(te.testException()); } }





    2

    上面的代码在编译器里面会出现错误,提示我们使用throws抛出异常,或者把throw new Exception()进行因此处理。改成这种

    <pre name="code" class="java">package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException() {
    		try{
    			int i=3/0;
    		}catch(Exception e){
    			try {
    				throw new Exception();
    			} catch (Exception e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    		}finally{
    			System.out.println("我运行finally代码块
    ");
    			
    		}
    		//System.out.println("异常处理结束!。!");
    		return "I am in finally";
    		
    	}
    	
    	
    	public static void main(String[] args)  {
    		// TODO Auto-generated method stub
    
    		TestException3 te=new TestException3();
    		
    	    
    			System.out.println(te.testException());
    		
    		
    	}
    
    }
    

    
    


    输出结果:

    java.lang.Exception
    	at com.wj.exception.TestException3.testException(TestException3.java:11)
    	at com.wj.exception.TestException3.main(TestException3.java:32)
    我运行finally代码块
    
    I am in finally
    









    3

    或者说是这种:

    <pre name="code" class="java">package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException()  throws Exception{
    		try{
    			int i=3/0;
    		}catch(Exception e){
    			
    				throw new Exception();
    			
    		}finally{
    			System.out.println("我运行finally代码块
    ");
    		}
    		//System.out.println("异常处理结束!

    !。"); return "I am in finally"; } public static void main(String[] args) { // TODO Auto-generated method stub TestException3 te=new TestException3(); try { System.out.println(te.testException()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }


    输出结果:

    
    
    我运行finally代码块
    
    
    java.lang.Exception
    <span style="white-space:pre">	</span>at com.wj.exception.TestException3.testException(TestException3.java:11)
    <span style="white-space:pre">	</span>at com.wj.exception.TestException3.main(TestException3.java:28)
    







    4

    这样改,非常easy,可是另一种更加奇葩的改法。能够使编译器不出错,例如以下:

    package com.wj.exception;
    
    public class TestException3 {
    
    	
    	public String testException()  {
    		try{
    			int i=3/0;
    		}catch(Exception e){
    			
    				throw new Exception();
    			
    		}finally{
    			System.out.println("我运行finally代码块
    ");
    			return "I am in finally";
    		}
    		//System.out.println("异常处理结束!

    "); //return "I am in finally"; } public static void main(String[] args) { // TODO Auto-generated method stub TestException3 te=new TestException3(); System.out.println(te.testException()); } }


    输出:

    我运行finally代码块
    I am in finally




         发现没有第四个代码。本来是跑出了一个异常的,可是没有输出不论什么的异常信息。

    并且把函数返回值改为void,在finally里面不使用return。则又会报错,这一点我不是非常明确了。难道在catch里面使用throw抛出的异常,在finally代码块里面使用return语句后,就被处理了嘛?要是被处理了怎么没得异常输出,还是输出的异常信息在栈里面被覆盖了?知道怎么回事的朋友,能够交流下。


    看了上面那么多,你是否对java中的异常有一定理解了?

    我在博客http://blog.csdn.net/hguisu/article/details/6155636里面看到一个样例,貌似比較经典。就借用下了,代码例如以下了:

    package com.wj.exception;
    
    public class TestException1 {
    
    	boolean testEx() throws Exception {  
    	boolean ret = true;  
    	try {  
    	ret = testEx1();  
    	} catch (Exception e) {  
    	System.out.println("testEx, catch exception");  
    	ret = false;  
    	throw e;  
    	} finally {  
    	System.out.println("testEx, finally; return value=" + ret);  
    	return ret;  
    	}  
    	}  
    
    	
    	boolean testEx1() throws Exception {  
    	boolean ret = true;  
    	try {  
    	ret = testEx2();  
    	if (!ret) {  
    	return false;  
    	}  
    	System.out.println("testEx1, at the end of try");  
    	return ret;  
    	} catch (Exception e) {  
    	System.out.println("testEx1, catch exception");  
    	ret = false;  
    	throw e;  
    	} finally {  
    	System.out.println("testEx1, finally; return value=" + ret);  
    	return ret;  
    	}  
    	}  
    
    	boolean testEx2() throws Exception {  
    	boolean ret = true;  
    		try {  
    		int b = 12;  
    		int c;  
    		for (int i = 2; i >= -2; i--) {  
    		c = b / i;  
    		System.out.println("i=" + i);  
    		}  
    		return true;  
    		} catch (Exception e) {  
    		System.out.println("testEx2, catch exception");  
    		ret = false;  
    		throw e;
    		} finally {  
    		System.out.println("testEx2, finally; return value=" + ret);  
    		return ret;  
    		}  
    		}  
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    
    		TestException1 testException1 = new TestException1();  
    		try {  
    		testException1.testEx();  
    		} catch (Exception e) {  
    			System.out.println("结束
    ");
    		e.printStackTrace();  
    		}  
    
    	}
    
    }
    

    假设不看答案,你能说出执行结果嘛?你能够到自己的编译器中执行下看下结果,在进行debug下,看看是否和你想的一样了。







          上面执行的结果例如以下:

    i=2
    i=1
    testEx2, catch exception
    testEx2, finally; return value=false
    testEx1, finally; return value=false
    testEx, finally; return value=false


       我进行过debug。所以我清楚执行的流程,可是对于内部的机制,还有点疑点,就像我在4所说的。finally中的return 会覆盖throw抛出的异常一样。真的是这种嘛,假设是这种话。上面的代码就能分析出和执行一样的输出结果了,能够试试,一起交流下。



    本文原创,转载请著明:http://blog.csdn.net/j903829182/article/details/39808307






















































































































  • 相关阅读:
    i++循环与i–循环的执行效率
    嵌入式linux通用截图工具
    imgsed发布
    Embedded Linux From Scratch
    WordPress Plupload插件未明跨站脚本漏洞
    Microsoft Internet Explorer 信息泄露漏洞
    WordPress 多个安全漏洞
    dedecms plus/search.php 注入漏洞利用EXP
    JBoss Enterprise Portal Platform多个跨站脚本执行漏洞
    WordPress organizer/page/users.php脚本多个跨站脚本漏洞
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6781076.html
Copyright © 2011-2022 走看看