java异常的深入学习以及异常处理时一些内存问题

通过如下链接系统学习java异常框架,并通过文章的评论和自己的测试得到如下总结

小结:
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
catch 块:用于处理try捕获到的异常。(catch中如果发生异常会抵消捕获的异常,总之最后一处发生的异常会被抛出,包括finally块)
finally 块:
无论是否捕获或处理异常,finally块里的语句都会被执行。
当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。


1.throw和return都可以使方法退出,而且可以互相覆盖
2.finally里如果有return会把catch里面throw出来的异常覆盖掉
  public  static  int  testInt ()  throws  Exception {
                  int  x ;
                  try  {
                        x  =  1 ;
                        throw  new  Exception () ;
//                    return x;
                  }  catch  ( Exception  e)  {
                        x  = 2  ;
                        throw  e ;
                  }  finally {
                        x  =  3  ;
                   return  x  ;
                  }
       }
3.程序运行关于栈和堆的问题,大家最好弄懂,无论那个编程语言都会涉及到,c里面叫指针,更高级语言里面叫引用,不懂这些有很多问题好难懂。了解这个问题的时候不要因为别人举例的语言不是java就抛弃,其实高级语言基础语法都差不多,不是蛮难看懂但是思想好重要
 

public  static  int  testInt (){
                  int  x ;
                  try  {
                        x  =  1 ;
                        return  x  ;
                  }  catch  ( Exception  e)  {
                        x  = 2  ;
                        return  x  ;
                  }  finally {
                        x  =  3 ;
                  // System.out.println("x:" + x);// return x;
      //              }
                  }
       }

这是《深入理解Java虚拟机-JVM高级特性与最佳实践》第二版书中的例子(P187~P188)。出现这种情况的原因是:在没有出线异常的情况下,先执行了x=1;然后执行return x;时,首先是将x的一个副本保存在本地变量表中,执行return之前必须执行finally中的操作:x=3;将x的值设置为了3,但是return时是将本地变量表中保存的x的那个副本拿出来放到栈顶返回。故没出异常时,返回值为1;出Exception异常或其子类异常时,返回值是2;如果出现非Exception异常,则执行完x=3之后,抛出异常,没有返回值。

对于这种异常时的执行情况,可以通过javap -verbose命令输出方法反编译后的字节码与异常表,从字节码层面上就能清晰的看出执行过程了。








return之前执行finally的话,return是返回了栈内存的副本(primitive类型数据副本 ,引用类型引用的副本),所以finally块如果操作的事primitive类型数据,或者重新分配了引用,String="456",会重新创建一个对象,所以不会影响引用副本。


     
      
       public  static  int  testInt ()  throws  Exception {
                  int  x ;
                  try  {
                        x  =  1 ;
                        throw  new  Exception ( "111" )  ;
//                    return x;
                  }  catch  ( Exception  e)  {
                        x  = 2  ;
                     //   throw  new  Exception ( "222" )  ;
                                                   return x;//返回x的副本(  primitive类型数据 )所以不会被finally块影响 return x=2
                  }  finally {
                        x  =  3 ;
//                    throw new Error();
//                System.out.println("x:" + x);
//                return x;
                  }
       }
      //引用类型的例子,
       public  static  String  testString (){
      String  name  =  "123" ;
      try  {
           throw  new  Exception () ;
           //return name;
      }  catch  ( Exception  e)  {
             return  name  ;//返回引用副本(对象类型)finally块name="456",是重新分配了引用 return name='123'
      } finally  {
             name  =  "456" ;
      }
       }
       static  StringBuffer  testStringBuffer (){    
             StringBuffer  name  =  new  StringBuffer (  "123" ) ;
             try  {      
                  throw  new  Exception () ;     
             }  catch  ( Exception  e)  {
                  System .  out .  println ( "catch name123: "  +  name .  hashCode ())  ;     
                  return  name  ;     //返回引用副本(对象类型)finally块name.append("456"),是对同一块引用的堆值得追加,所以影响了return name='123456'
             } finally {
                  name .  append ( "456"  ) ;
                  System .  out .  println ( "finally name456: "  +  name .  hashCode ())  ;
                  name  =  new  StringBuffer ( "abc"  ) ;   
                  System .  out .  println ( "finally name: "  +  name .  hashCode ())  ;     
             }    
     }
     

 
  static StringBuffer testStringBuffer () throws Exception {   
            StringBuffer name =  new  StringBuffer ( "123" ) ;
            try {      
                 throw new Exception () ;     
            } catch ( Exception e) {
                 System . out . println ( "catch name123: "  + name . hashCode ()) ;     
                 return name ;    
            } finally {

  name . append ( "456" ) ;
 System . out . println ( "finally name456: " + name . hashCode ()) ;
                 name = new StringBuffer ( "abc" ) ;  
                 System . out . println ( "finally name: " + name . hashCode ()) ;     
                 throw new Exception () ;      //抛出异常(抵消前面的所有异常)
            }     
      }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值