java第九天---异常处理和日志

一、异常处理

  1、什么是异常?

    异常是指程序运行时产生的异常事件,通常是由外部问题(如硬件错误)所导致的。在java等面向对象的编程语言中异常属于对象。

  2、异常体系

thorwable:所有异常的祖宗

      error:错误,致命性错误

         -> vritualMachineException

         -> ServiceConfigurationException

         -> ThreadDeath

      exception:编译器异常

         ->RuntimeException

            ->NullPointException

            ->ArithmeticException

            ->InputMismatchException

            ->ArrayIndexOutOfBoundsException

            ->MissingResourceException

         ->IOException

            ->FileNotFoundException

            ->ObjectStreamException

            ->EOFException

         ->ClassNotFoundException

         ->SQLExcepiton
View Code

  error:该类异常是比较严重的错误,一般指jvm错误,仅靠程序本身无法更改。

  exception:编译器异常,在编写程序时出现的异常。子类RuntimeException异常,是程序运行时出现的异常,将异常处理处理掉,程序下边代码还能与        运行

  3、异常处理的作用

    不至于让程序因为一些不致命的错误而导致不能运行

  4、处理异常的方法有两类:

    抛出异常、异常捕获

  5、抛出异常 ---  throw、throws

    throw:抛出方法中可能出现的异常对象。如果是非RuntimeException,需要在方法的声明时加上该异常的抛出(throws语句)或者在方法中对异常       进行处理try---catch语句,否则编译报错。

    throws:在方法的尾部用来声明方法中可能出现的异常,抛给调用者进行异常,或者调用者选择继续抛出,如果都不处理,则抛出到虚拟机,程       序无法运行。

  示例一:异常抛出

public class ArrayUtil {
//获取数组中的最大值
    public static int arrMax(int[] arr){
        if(arr==null)
            throw new NullPointerException("数组为空");
        if(arr.length==0)
            throw new ArrayIndexOutOfBoundsException("数组长度为零");
        int max=arr[0];
        for(int i=0;i<arr.length;i++){
            if(arr[i]>max){
                max=arr[i];
            }
        }
        return max;
    }
}
View Code
public class DemoTest {
    public static void main(String[] args) {
        int[] arr={10,35,61};
        int[] arr1={};
        ArrayUtil.arrMax(arr1);
        System.out.println(arr.length);
    }
}
View Code 

此例仅是异常抛出,并没有异常处理。导致出现异常后,程序直接停止

    示例二:throws抛出异常

public class DateFormat {
    public static void main(String[] args) throws ParseException {
        String ss="2019-09-12 dsfsdf 12:12:12";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = simpleDateFormat.parse(ss);
        System.out.println(parse);
    }

}
View Code

  该例中,将异常抛给mian()方法,再将异常抛给虚拟机,出现错误时,程序直接停止。

 

  throws语句将异常抛给调用者(方法)--->往上抛------>往上抛---->main()--->jvm虚拟机,在到达虚拟机之前如果没有处理,程序停止

  示例:

public class DateF {
//   方法名后的throws将异常抛给调用者
    public static Date getDate(String str) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = simpleDateFormat.parse(str);
        return parse;
    }
}
View Code
public class DateTest {
//main方法中调用有异常抛出的方法,然后再main方法中抛给jvm
    public static void main(String[] args) throws ParseException {
        String ss="2019-09-12 dsfsdf 12:12:12";
        Date date = DateF.getDate(ss);
        System.out.println(date);
    }
}
View Code

  6、try-catch 捕获并解决

    思考:我们以前的程序中只要出错,就会停止,这样是不行的。我们不能因为一点不致命的错误就让整个程序停止,所以我们可以将一些异常进行处理。

    异常处理的格式:Exception是所以异常的父类。 try{代码块①}catch(Exception e){代码块②:异常处理}

      流程:当代码块①没有异常时,此处后边的代码正常执行。如果代码块①有异常,就会先执行代码块②。然后接着执行try--catch后的代码。

    示例:

public class DateF {
//   方法名后的throws将异常抛给调用者
    public static Date getDate(String str) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = simpleDateFormat.parse(str);
        return parse;
    }
}
View Code
public class DateTest {
    public static void main(String[] args){
        String ss="2019-09-12 dsfsdf 12:12:12";
        Date date = null;
//异常不再抛出,使用try-catch处理
        try {
            date = DateF.getDate(ss);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(date);
    }
View Code

  7、多重catch

    多重catch中,catch只会执行一个。代码块中可能有多个异常,可以通过多个catch进行捕获,异常存在父子关系,但是子类是放在父类之前的 

public class DateF {
//   方法名后的throws将异常抛给调用者
    public static Date getDate(String str) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = simpleDateFormat.parse(str);
        return parse;
    }
}
View Code
public class DateTest {
    public static void main(String[] args){
        String ss="2019-09-12 dsfsdf 12:12:12";
        Date date = null;
        int a=10;
        int b=12;
        int c=0;
        try {
           //这里可能有异常
            date = DateF.getDate(ss);
           //这里也可能有异常 
            c=a/0;
        } catch (ParseException e) {
            e.printStackTrace();
        }catch (ArithmeticException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println(date);
        System.out.println(c);
    }
}          
View Code

黑色箭头标识运行顺序,红色箭头标识异常关系,黄色箭头标识发生异常时对应的catch

    运行结果:

    finally关键字:可以关闭io,数据库连接    

        try {
            date = DateF.getDate(ss);
            c=a/0;
        } catch (ParseException e) {
            e.printStackTrace();
        }catch (ArithmeticException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }finally {  //finally是必然会执行的,一般用来关闭io流,关闭数据库连接
            System.out.println("jieshu");
        }   

 

  8、自定义异常类型

      ①我们可以自定义一些异常类型来根据我们的场景进行运用。

      ②定义格式

        权限修饰符  class 类名  extends   Exception{

          public 类名(String msg){//构造方法,msg提示类型错误信息

            super(msg);

          }

        };

      ③示例:定义一个Person类,类中有一个性别属性,我们要保证输入的属性值为男或女,不然就爆出异常,程序继续向下执行

package com.fy.day09.demo3;

public class Person {
    private int age;
    private String name;
    private String sex;

    public Person() {
    }

    public Person(int age, String name, String sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) throws SexException {
        if("男".equals(sex) || "女".equals(sex)){
            this.sex = sex;
        }else {
          throw new SexException("性别必须为男或女");
        }

    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}
View Code
public class SexException extends Exception{
    public SexException(String msg){
        super(msg);
    }
}
View Code
public class DemoTest {
    public static void main(String[] args) {
        Person p = new Person();
        p.setAge(19);
        p.setName("小红");
        try {
            p.setSex("dsf");
        } catch (SexException e) {
            e.printStackTrace();
        }
        System.out.println(p);
    }
}
View Code

二、日志

  1、日志类的作用

      可以帮我们记录程序的运行记录,比如某时谁登录,做了那些操作

  2、使用日志类

    ①在项目中添加log4j.jar包       

        IDEA中添加外部jar包

        项目的src文件夹上--->右键-新建文件夹或包lib

        将jar文件拷贝到lib目录中

        lib目录上右键-【Add as LIbrary】

     ②在项目中添加日志配置文件

      log4j.properties:

### 把日志信息输出到控制台  ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n
### 把日志信息输出到文件:anbo.log ###
log4j.appender.file=org.apache.log4j.FileAppender
#指定输出目录
log4j.appender.file.File=AAA.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l  %m%n
### 设置优先级别、以及输出源 ###
log4j.rootLogger=info,stdout,file

     ③使用

public class DemoTest {
    public static void main(String[] args) {
        Logger demoTest = Logger.getLogger("DemoTest"); //获取日志对象
        demoTest.info("info级别日志");
        demoTest.warning("warn级别");
    }
}
    

    Debug->debug调试级别的日志

    INFO->info正常级别的日志

    WARN->warn警告级别的日志

    ERROR->error错误级别的日志

    FATAL->fatal致命级别的日志

  在配置文件中,log4j.rootLogger后设置的优先级别越高,打印的日志信息越少,设置为fatal的话,则其余四个均不能打印  

 

posted @ 2020-12-15 22:27  橙汁one  阅读(265)  评论(0编辑  收藏  举报