ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java 异常

2022-07-29 09:03:32  阅读:127  来源: 互联网

标签:Java 代码 System log4j catch 异常 public


第七章、异常

Java 语言中,将程序执行中发生的不正常情况称为“异常”。

1. 异常体系

image

Error(错误):

Java 虚拟机无法解决的严重问题,如:JVM 系统内部错误、资源耗尽等严重情况。比如:StackOverflowError[栈溢出]和OOM(out of memory),Error 是严重错误,程序会崩溃。

Exception:

其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等待,Exception 分为两大类:运行时异常[程序运行时,发生的异常]和编译时异常[编译时,编译器检查出的异常]。

运行时异常,编译器检查不出来。一般是指编程时的逻辑错误,是程序员应该避免其出现的异常。java.lang.RuntimeException类及它的子类都是运行时异常。对于运行时异常,可以不做处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。编译时异常,时编译器要求必须处理的异常。

2. 如何处理异常

在 Java 中,把异常信息封装成了一个类。当出现了问题时,就会创建异常类对象并抛出异常相关的信息(如异常出现的位置、原因等)。

处理异常的方式:

1)手动去修改有问题的代码

2)使用debug去调试代码

3)使用判断选择结构去修改代码:if...else

弊端:

1)手动改代码,不靠谱,你怎么知道哪里会发生异常?

2)使用选择结构,太繁琐,不好维护

解决问题:

使用 java 提供的异常处理机制,来处理和捕获异常,保证程序的正常运行,提高程序的健壮性和可维护性。

3. java常见异常分类

Throwable类: Throwable 类是Java语言中所有错误和异常的超

类。

​ |--- 子类error : 一个 Error 是的子类Throwable 表示严重的问

题。该问题程序员是无法处理的,没有办法解决,一般不处理该问题。

|--- 子类 `Exception` : `异常` 及其子类是 `Throwable` 的形式,表示合理应用程序可能想要捕获的条件。该问题,程序员可以进行处理,捕获异常。

		| --- checked异常/检查异常/编译期异常:程序员可以在写代

码的时候,可以发现的异常,代码有红色波浪线

​ |---RuntimeException: 运行期异常/非检查异常:该异常在编

译期不报错的,只有在程序运行的时候,才会出现异常,该异常要捕获!

4. 常见异常处理机制有哪些?

1)jvm 默认有一套异常处理的方式。

2)使用 try - catch :异常捕获机制

使用 tay - catch 来捕获异常,来对异常进行处理

语法

try{
    //可能会发生异常的代码
}catch(异常类型 变量名){ //对异常进行处理
    
}

快捷键:先写代码,然后选中代码,按 ctrl+alt+T,再选 try...catch

3)多重 catch

通过多重 catch,可以捕获具体的异常。

注意问题:

1)使用多个 catch 来捕获异常

2)catch 执行是有顺序的,一般范围小的异常,放在最前,最后写Exception

3)异常捕获成功之后,只会捕获一次异常,会结束 try...catch,继续执行后面的程序

4)catch 中的异常的变量名,可以重复,没有影响

4)try-catch-finally

finally:可以写,也可以不写;如果写了,那么finally中的代码,会执行。

一般应用于:I/O流,jdbc操作,关闭流,关闭连接

语法:

try{
    //可能会发生异常的代码
}catch(异常类型 变量名){ //对异常进行处理
    
}finally{
    //默认自动执行
}

细节问题:

  1. 如果代码正常运行,那么程序一定会执行 finally 中的代码。
  2. 如果代码出现了异常,那么先执行 catch 中的代码,然后再执行 finally 中的代码。(try 中的发生异常位置之后的代码,不会再执行了)
  3. 如果代码正常运行,try 中有 return ,那么会先执行 finally 中的代码,然后再 return;
  4. 如果代码出现了异常,并且 try 中有 return ,那么遵循规则2;
  5. finally 唯一不会执行情况:System.exit(0):强制退出

案例

package com.xunfang.homework.topic03;

import java.util.InputMismatchException;
import java.util.Scanner;

public class NewDivide {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        try {
            System.out.print("请输入被除数:");
            int num1 = input.nextInt();
            System.out.print("请输入除数:");
            int num2 = input.nextInt();
            System.out.println("num1 / num2 = " + num1/num2);
//            System.exit(0);
//            return;
        } catch (InputMismatchException e){
            e.printStackTrace();
            System.err.println("被除数和除数必须是整数");
        }catch (ArithmeticException e){
            e.printStackTrace();
            System.err.println("除数不能为零");
        } catch (Exception e) {
            //打印异常的堆栈信息- 什么异常,异常发生的位置
            e.printStackTrace();
            //err:打印的颜色会变成红色
            System.err.println("程序发生了异常");
        }finally {
            System.out.println("感谢使用本程序!");
        }
        System.out.println("程序继续运行...");
    }
}

5)声明异常 throws

throws:抛出异常,表示该位置可能发生异常,但是不具体处理,让后面的程序去处理异常。

语法:

//表示当前的方法,抛出了什么异常!
...方法名() throws 异常类型1,异常类型2,...{
    
}

异常抛出的处理方式:

//1.main方法捕获异常 - 这种方式
//2.main也不想捕获,摆烂,抛出异常。(JVM的默认方式)

6)Exceptiion 的所有的异常类分类如何划分:

运行时异常:

RuntimeException - 父类

常见的运行时异常:

异常 解释
NullPointerException 空指针异常
ArithmeticException 算术异常
ClassCastException 类型强制转换异常
ArrayIndexOutOfBoundsException 数组下标越界异常
StringIndexOutOfBoundsException 字符串索引越界异常
InputMismatchException 控制台输入类型错误异常

编译时异常:

写代码的时候,红色波浪线。

常见的编译时异常:

异常 解释
FileNotFoundException 文件未找到异常
ClassNotFoundException 无法找到指定的类异常
SQLException 操作数据库异常
IOException 输入输出异常
NumberFormatException 字符串转换为数字异常
NoSuchMethodException 方法未找到异常

细节问题:

1、在代码的运行过程中,发生的异常,需要捕获

2、在代码的编写过程中,发生的异常,一般表现为红色波浪线

7)抛出异常 throw

表示 程序员 认为该位置 肯定会有异常,进行手动抛出异常。

语法:

throw new 异常类型("xxx")

8)throw 和 throws 有何区别???

  1. throws:声明异常,表示可能会有异常,写在方法名的后面,把异常抛出,后面代码处理。
  2. throw:手动抛出异常,表示肯定会员异常,写在带啊吗中,把异常抛出,后面代码处理
package com.xunfang.demo.demo2;

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) throws Exception {
        if (age >= 16 && age <= 32){
            this.age = age;
        }else {
            throw new Exception("年龄不合法!!!");
        }
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) throws Exception {
        if (sex == '男' || sex == '女') {
            this.sex = sex;
        } else {
            throw new Exception("性别不合法!!!");
        }
    }
}


package com.xunfang.demo.demo2;

import java.util.Scanner;

public class PersonTest {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Person person = new Person();
        System.out.print("请输入姓名:");
        person.setName(input.next());
        try {
            System.out.print("请输入年龄:");
            person.setAge(input.nextInt());
            System.out.print("请输入性别:");
            person.setSex(input.next().charAt(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("程序继续执行");
    }
}

5. 程序强制退出的方式

System.exit(0)

6. 程序强制退出和 return 的区别?

程序强制退出:结束程序

return:方法返回

7. 异常在方法重写中细节

子类关系中,使用异常

1)如果父类方法抛出异常,子类可以不抛出异常

2)子类不能比父类抛出的异常范围大

3)子类可以比父类抛出的异常类型多

public abstract class Father {
    public abstract void show() throws NullPointerException, Exception;
}


public class Son extends Father{

    @Override
    public void show() throws Exception,ArithmeticException,RuntimeException,NullPointerException{
        System.out.println("重写");
    }
}

8. 自定义异常

自定义异常类,要继承Exception类,并重写构造方法

public class AgeException extends Exception{
    public AgeException(){}

    public AgeException(String message){
        super(message);
        System.out.println("这是一个自定义的异常类");
    }
}

public class Person {
    private int age;
    public int getAge() {
        return age;
    }

    public void setAge(int age) throws Exception {
        if (age >= 16 && age <= 60){
            this.age = age;
        }else {
            throw new AgeException("年龄不合法!!!");
        }
    }
}

public class PersonTest {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        Person person = new Person();
        try {
            System.out.print("请输入年龄:");
            person.setAge(input.nextInt());
        } catch (AgeException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("程序继续执行");
    }
}

9. 扩展:Log4j 日志的使用

日志:记录代码操作

Log4j:是一个日志的框架,可以在控制台和日志文件中,体现出后端的代码输出信息,方便我们去查找代码的信息和错误,和日志分析

使用步骤:

1)导入第三方的 jar 包

2)在src目录下,去引入日志的配置文件log4j.properties

配置文件:便是可以实现一些项目的配置信息

配置文件的分类:xx.xml xx.properties xx.yaml xx.yml properties

配置文件的规则:属性1.属性2.xx.xx = 值

3)使用日志的类的对象,来使用日志的操作。

#根logger设置
log4j.rootLogger = INFO,console,file

### 输出信息到控制台###
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [%p] %d{yyyy-MM-dd HH:mm:ss} method: %l----%m%n

###输出INFO 级别以上的日志文件设置###
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File = D:/2022.7.22_test.log
log4j.appender.file.Append = true
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} method: %l - [ %p ]----%m%n

用法:

导包:import org.apache.log4j.Logger;
创建日志对象
public Logger logger = Logger.getLogger(Person.class);
打印日志消息...
logger.info("年龄合法~");


public static Logger logger = Logger.getLogger(Person.class); //注意此处为static
再调用方法:报程序错误,和错误内容
logger.error("程序错误",e);

10. 总结

image

标签:Java,代码,System,log4j,catch,异常,public
来源: https://www.cnblogs.com/hwphwc/p/16531011.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有