JavaSE复习_7 异常

△子父类涉及的异常问题:
     1.子类在覆盖方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类,且只能抛出异常的子集
     2.如果父类抛出了多个异常,子类只能抛出父类异常的子集,如果父类的方法没有抛出异常,那么子类重写方法时一定不能抛,只能捕捉
△throw和throws:
     1.throw声明在方法内部,抛出的是异常的对象。
     2.throws生命在方法上,抛出的是异常类
△编译异常和运行时异常:编译异常必须对其进行处理,而运行时异常不需处理.编译时的异常称为已检查异常,运行时的异常称为未检查异常。
△JDK1.7新增异常的特性:catch(Exception | NullpointerException e):捕获异常,这里注意,参数名只有一个,另外中间只能用"|"不能用"||".并且两个异常不能互相是继承关系。
△多catch语句,父类异常一定要放在最下面。
在一个异常体系捕捉后,catch语句块里面抛出另外一个异常是相当实用的做法。称为异常的转换。
△finally就算碰到return也会继续执行
△finally只用于发生异常且未捕捉到的时候,执行关闭资源的动作,其他情况下,其语句等同于正常的语句,按照正常的顺序执行。
△finally的返回值会将try语句的返回值覆盖
public static int f(int n){
               try{
                      int r =n *n ;
                      return r ;
              }
               finally{
                      if(n ==2)
                            return 6;
              }
       }

该语句当n=2时,返回6。

△try finally语句中,finally语句中如果关闭抛出了异常,那么后抛出的异常将会把刚抛出的异常给覆盖

class XyyException extends Exception{
        public XyyException(String s ){
               super(s );
       }
}
class HlhException extends Exception{
        public HlhException(String s ){
               super(s );
       }
}
public class Demo {

        public static void main(String[] args) throws XyyException, HlhException {
               f();
       }

        public static void f() throws XyyException, HlhException {
               int x =2;
               try{
                      x= x*2;
                      throw new XyyException("try");
              }
               finally{
                      if(x ==4){
                            throw new HlhException("finally");
                     }
              }
       }

}
异常为:
Exception in thread "main" string.Demo.HlhException: finally
       at string.Demo.Demo.f( Demo.java:26)
       at string.Demo.Demo.main( Demo.java:15)
解决这种方法的步骤为:采用带资源的try语句,在try()括号里实现了AutoCloseable接口的类都可以在调用try后关闭资源,(此时try语句里的资源关闭发生的异常将会被抑制,不会被抛出)。
△关于异常finally对于返回值的覆盖,有以下几点细节:
  finally语句在return执行后返回前执行。对于基本类型,return可以确定的是进入finally前的返回值。对于引用数据类型,return可以确定的是返回的对象内容。用两个示例加以说明:
public static int f(){
            int x=10;
       try{
        System.out.println(12/0);
        return x;
       } catch(Exception e) {
        x=20;
        return x;
       }
       finally {
        x=30;
        if(x==30)
              return x;
       }
}

  这个代码finally会将return30,因为finally中的return会将catch中的return覆盖,而如果没有return x,则该方法返回20,因为x仅仅赋值,但是返回的此时已经确定好了值.即在finally语句在return执行后返回前执行。

import java.util.*;

public class FinallyTest6
{
    public static void main(String[] args) {
        System.out.println(getMap().get("KEY").toString());
    }

    public static Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");

        try {
            map.put("KEY", "TRY");
            return map;
        }
        catch (Exception e) {
            map.put("KEY", "CATCH");
        }
        finally {
            map.put("KEY", "FINALLY");
            map = null;
        }

        return map;
    }
}

  这个代码运行结果是finally。因为在try中即返回了引用所指向的对象(即确定的是对象),随后对对象的操作都会改变返回值,但是在finally代码块的最后一句将引用指向空,对于对象不构成任何影响,原对象返回。

△断言机制:assert关键字
 格式为:assert 条件;
或assert 条件:表达式;(表达式部分的唯一目的是产生一个消息字符串。)    
 当assert的条件为false的时候,将会抛出一个有关键字构成的AssertionError异常。
 利用java -ea打开assert,即可进入断言机制模式,默认情况下为关闭。
△记录日志
  Logger logger=Logger.getLogger("Demo");               //获得一个记录器,其名为Demo
  logger.setLevel(Level.ALL)                                        //获得记录器的等级
  然后利用;logger.entering() logger.exiting记录进入方法,离开方法。(需要手动记录)
  处理器:可以利用FileHandler将日志输出到文件。
  FileHandler fh=new FileHandler( "MyLogger.txt");
 fh.setLevel(Level. FINE);
 logger .addHandler(fh);                 //将处理器添加到日志记录器中,可以添加多个
 但是这样输出的文件将会是XML格式,不方便阅读因此需要定义格式化器,然后将其添加到处理器
 示例:
package io.project.one;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class Demo2 {
        public static void main(String[] args) {
              Logger logger=Logger. getLogger("io.project.one.Demo2");
               logger.setLevel(Level. FINE);
               try {
                     FileHandler fh= new FileHandler("MyLogger.txt" );
                      fh.setLevel(Level. FINE);
                      fh.setFormatter( new MyFormatter());
                      logger.addHandler( fh);

                      logger.fine( "进入main函数" );
                      int x =2;
                      int y =3;
                      add(x,y);
                      logger.exiting( "io.project.one.Demo2", "main" );
              } catch (Exception e ) {
                      e.printStackTrace();
              }
       }

        public static void add(int x, int y) {
              Logger logger=Logger. getLogger("io.project.one.Demo2");
               logger.fine( "io.project.one.Demo2");
              System. out.println("x+y" );
               logger.fine( "io.project.one.Demo2");
       }

}
class MyFormatter extends Formatter{

        @Override
        public String format(LogRecord record ) {
               return "类别:" +record .getLevel()+"....信息:"+ record.getMessage();
       }
}
这样输出的信息:
类别:FINE....信息:进入main函数类别:FINE....信息:io.project.one.Demo2类别:FINE....信息:io.project.one.Demo2。
简单易懂。
△调试技巧
  step into:跟踪到每个方法的内部(F5)
  step over:定位到下一行,不跟踪到方法的内部。(F6)
  step return:返回原来调用此方法的方法。(F7)
  step resume:跳到下一个断点(F8)
  调试窗口中,断点视图可以设置条件断点(当且仅当某个表达式值为true,才在此断点暂停。)点击断点视图中的断点--右键breakpoints properties--Conditional--设置断点的值。
  也可以添加异常断点,保证遇到某个异常的时候,仍然能够继续调试。
△通过注释规避编译器检查
 规避对于方法所有代码的检查:
     @SuppressWarnings("unchecked" )
        public void setFirst(T first) {
               this.first = first ;
       }
 对于调用方法时的语句进行规避检查:  
     @SuppressWarnings("unchecked" )
     Pair<String> mm=ArrayAlg. minmax(words);
原文地址:https://www.cnblogs.com/hlhdidi/p/5595835.html