java异常(四)

# java异常(四)
一.什么是异常?

异常(Exception 例外)指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
异常指的并不是语法错误,语法错了,编译不通过,不会产生字节码文件,根本不能运行.
Java虚拟机处理异常的方式是中断处理。

二.异常的体系?

JAVA将所有的异常封装成为一个对象,其根本父类为java.lang.Throwable,Throwable有两个子类:Error和Exception。
Error:Error对象表示一个程序错误,指的是底层的、低级的、不可恢复的严重错误。此时程序一定会退出,因为已经失去了运行所必须的物理环境。对于Error错误我们无法进行处理,因为我们是通过程序来应对错误,可是程序已经退出了。
Exception有两个子类:
运行时异常:Runtime exception(未检查异常)可以在编程时避免,可处理可不处理,未检查异常是因为程序员没有进行必要的检查,因为他的疏忽和错误而引起的异常。一定是属于虚拟机内部的异常(比如空指针)。(在运行时期,检查异常.在编译时期,运行异常不会被编译器检测(不报错)。(如数学异常))
编译时异常:非Runtime exception(已检查异常)必须进行处理。(在编译时期,就会检查,如果没有处理异常,则编译失败。(如日期格式化异常))
注意:无论是未检查异常还是已检查异常在编译的时候都不会被发现,在编译的过程中检查的是程序的语法错误,而异常是一个运行时程序出错的概念。
在这里插入图片描述

三.如何应对这些异常。

应对未检查异常就是养成良好的检查习惯。
已检查异常是不可避免的,对于已检查异常必须实现定义好应对的方法。
已检查异常肯定跨越出了虚拟机的范围。(比如“未找到文件”)

四.jvm默认处理异常的方式。

如果程序出现了问题,我们没有做任何处理,最终JVM 会做默认的处理
处理方式:

  • 把异常的名称,错误原因及异常出现的位置等信息输出在了控制台
  • 程序停止执行

五.异常的处理(对于所有的已检查异常都要进行处理,如果不处理编译出错)

异常的形成机制:
当一个方法中有一条语句出现了异常,它就会throw(抛出)一个异常对象(throw 异常对象),然后后面的语句不会执行,返回上一级方法,其上一级方法接受到了例外对象之后,有可能对这个异常进行处理,也可能将这个异常转到它的上一级。
当一个方法中出现了异常,没有进行异常处理,方法就会把异常对象作为返回值返回。如果有异常进入虚拟机,那么虚拟机就会立刻中止程序的执行。

  • 1.抛出
    在方法的定义中声明方法可能抛出的异常(可以抛出的是实际产生异常的父类的异常对象),用(throws 异常类名,异常类名),声明这个方法将不处理异常,并将这个异常对象向上一级返回,如果所有的方法均不进行处理,返回到主方法,程序中止。(要避免所有的方法都返回的使用方法,因为这样出现一个很小的异常就会令程序中止)。
    出错的方法有可能是JDK,也可能是程序员写的程序,无论谁写的,抛出一定用throw。
    如果在方法的程序中有一行throw new Exception(),返回错误,那么其后的程序不执行。因为错误返回后,后面的程序肯定没有机会执行,那么JAVA认为以后的程序没有存在的必要。
    子类方法不可比父类方法抛出更多的异常。如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常。如果父类型无throws时,子类型也不允许出现throws。此时只能使用try catch。
    父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出
  • 2.处理
try {
	可能出现异常的代码;
} catch(异常类名 变量名) {
	异常的处理代码;
} catch(异常类名2 变量名){
	异常的处理代码; 
}finally{
    释放资源
}

//以上三种写法都可以。
try{..}catch(..){..}
try{..}catch(..){}finally{..}
try{..}finally{}

try catch的执行顺序。

  • 1.try块中的代码如果没有出现异常,就会跳过catch,正常执行。
  • 2.try中如果发现错误,即跳出try块去匹配catch,那么try异常语句后面的语句就不会被执行。
    一个try可以跟进多个catch语句,用于处理不同情况。当一个try只能匹配一个catch。
    catch中的异常类型,子类型写在父类型的前面,最后写Exception。(我们可以写多个catch语句,但是不能将父类型的exception的位置写在子类型的excepiton之前,因为这样父类型肯定先于子类型被匹配,所有子类型就成为废话,java中是不允许写废话的,所以编译会出错。)
  • 3.在try,catch后还可以再跟一子句finally。其中的代码语句无论如何(无论有没有异常)都会被执行(因为finally子句的这个特性,所以一般将释放资源,关闭连接的语句写在里面),如果finally有return语句,永远返回finally中的结果,避免该情况. 。finally中的代码在和try中的代码的冲突时,finally中的代码一定会被执行且会忽略try中的代码。但是System.exit(0);(虚拟机退出语句)则不会去执行fianlly中的代码。

六.如何知道在编写的程序中会出现例外呢?

1.调用方法,查看API中查看方法中是否有已检查错误。
2.在编译的过程中看提示信息,然后加上相应的处理。

七.自定义异常

7.1为什么要自定义异常?
很多异常,这些异常很可能在JDK中没有定义过。
7.2什么是自定义异常类?
一个类继承了java.lang.Exceptionjava.lang.RuntimeException类,那么这个类就是一个异常类

7.3Throwable成员方法.

方法名说明
public String getMessage()返回此 throwable 的详细消息字符串。
public String toString()返回此可抛出的简短描述。
public void printStackTrace()把异常的错误信息输出在控制台。

八.throw 抛出异常处理
在java中,提供了一个throw关键字,它用来抛出一个指定的异常对象

  • 创建一个异常对象。封装一些提示信息(信息可以自己编写。)
  • 需要将这个异常对象告知给调用者。怎么告知呢?怎么将这个异常对象传递到调用者处呢?通过关键字throw就可以完成。throw 异常对象。throw用在方法内,用来抛出一个异常对象,将这个异常对象传递到调用者处,并结束当前方法的执行。
修饰符 返回值类型 方法名(参数列表) [throws 异常的类型] {
    if (判断条件) {
        throw new 异常对象("异常的原因");	
    }
}

throw 与 throws的区别

throw抛出的异常,必须与throws抛出的异常类型相同,或者throw抛出的异常是声明允许抛出异常的子孙类。
throw会导致方法返回,可以看成return,异常情况。
throws
用在方法声明后面,跟的是异常类名
表示抛出异常,由该方法的调用者来处理
表示出现异常的一种可能性,并不一定会发生这些异常
throw
用在方法体内,跟的是异常对象名
表示抛出异常,由方法体内的语句处理
执行throw一定抛出了某种异常

开发中的两个道理:

如何控制try的范围:根据操作的连动性和相关性,如果前面的程序代码块抛出的错误影响了后面程序代码的运行,那么这个我们就说这两个程序代码存在关联,应该放在同一个try中。
对已经查出来的例外(异常),有throw(消极)和try catch(积极)两种处理方法。对于throws把异常抛到try catch能够很好地处理例外的位置(即放在具备对例外进行处理的能力的位置)。如果没有处理能力就继续上抛。

九.断言是一种调试工具(assert)

其后跟的是布尔类型的表达式,如果表达式结果为真不影响程序运行。如果为假系统出现低级错误,在屏幕上出现assert信息。

log4j如何使用

1 什么是日志?
日志用来记录用户操作、系统运行状态等,是一个系统的重要组成部分。
2.日志的作用?

  • 了解线上系统的运行状态

  • 快速准确定位线上问题

  • 发现系统瓶颈

  • 预警系统潜在风险

  • 挖掘产品最大价值
    不好的日志导致

  • 对系统的运行状态一知半解,甚至一无所知

  • 系统出现问题无法定位,或者需要花费巨大的时间和精力

  • 无法发现系统瓶颈,不知优化从何做起

  • 无法基于日志对系统运行过程中的错误和潜在风险进行监控和报警

  • 对挖掘用户行为和提升产品价值毫无帮助
    2 日志分类
    日志从功能来说,可分为诊断日志、统计日志、审计日志。
    3 日志级别?
    Log4j定义了8个级别的log(除去OFF和ALL,可以说分为6个级别),优先级从高到低依次为:OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、 ALL。

  • ALL

    最低等级的,用于打开所有日志记录。

  • TRACE

    designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。

  • DEBUG

    DEUBG 级别的主要输出调试性质的内容,该级别日志主要用于在开发、测试阶段输出。该级别的日志应尽可能地详尽,便于在开发、测试阶段出现问题或者异常时,对其进行分析。

  • INFO

    INFO日志主要记录系统关键信息,旨在保留系统正常工作期间关键运行指标,开发人员可以将初始化系统配置、业务状态变化信息,或者用户业务流程中的核心处理记录到INFO日志中,方便日常运维工作以及错误回溯时上下文场景复现。建议在项目完成后,在测试环境将日志级别调成 INFO,然后通过 INFO 级别的信息看看是否能了解这个应用的运用情况,如果出现问题后是否这些日志能否提供有用的排查问题的信息。

  • WARN

    WARN 级别的主要输出警告性质的内容,这些内容是可以预知且是有规划的,比如,某个方法入参为空或者该参数的值不满足运行该方法的条件时。在 WARN 级别的时应输出较为详尽的信息,以便于事后对日志进行分析

  • ERROR

    ERROR 级别主要针对于一些不可预知的信息,诸如:错误、异常等,比如,在 catch 块中抓获的网络通信、数据库连接等异常,若异常对系统的整个流程影响不大,可以使用 WARN 级别日志输出。在输出 ERROR 级别的日志时,尽量多地输出方法入参数、方法执行过程中产生的对象等数据,在带有错误、异常对象的数据时,需要将该对象一并输出

  • FATAL

    指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。

  • OFF

    最高等级的,用于关闭所有日志记录。

    4 日志
    如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。og4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。默认级别是:ERROR

    log4j配置文件的文件名为:log4j.propertis;直接复制到src目录下,会自动加载到bin下。

### 设置 debug是设置类型。###
log4j.rootLogger = debug,stdout,D,E
###stdout打印到控制台###
### 输出信息到控制抬 ###
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 = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n

### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG 
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log 
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR 
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
//创建log对象
Logger log = LogManager.getLogger("本类名.class");
log.error("这是个错误");
log.debug("我会用日志");
log.trace("这trace错误");
log.info("这是个info错误");
log.fatal("这是个fatal错误");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值