(1)前面所遇到的异常(类型Class):
(2) 异常的含义
a.异常:在执行某件事的过程中,出现了不符合预期的情况
如:电梯异常、地铁异常、电路异常…
b.程序中的异常:
在程序运行过程中出现的问题,会导致程序中断结束(异常)
java提供了一套异常处理机制来解决我们使用过多的if判断问题(补不全、代码维护性变差、阅读困难)
关于异常的关键词:
try:尝试
catch:抓住
finally:最终的
**throw:**扔
**throws:**扔
// 在try代码块中执行有可能出现异常的代码段
// 当出现了异常的情况下,catch(异常类型)标注的异常会捕获合适的异常(如果代码出现了catch里面的异常类型就会捕获)
// 捕获到合适的异常之后,可以对异常采取修复/处理手段
// 代码可以继续正常的执行下去
try{
// 可能会出现异常的代码
}catch(异常类型){
// 对异常的修复/处理
}
/*
执行流程:
在执行try块代码时
当出现:InputMismatchException情况时,会立刻结束try块代码,JVM会帮你构建一个异常对象(nextInt()代码中有此源码) new InputMismatchException(nfe.getMessage());
然后我们的catch块就可以捕获到此异常 形参会接收此对象引用,进行正常处理,处理完继续正常运行。
当出现:ArithmeticException情况时,会立刻结束try块代码,JVM会帮你创建的异常对象,无法被catch块所接收,相当于方法的形参和实参不一致,所以catch不会捕获异常,JVM会将你的异常直接以堆栈跟踪的形式打印出来,并且会结束我们的程序
*/
Scanner input = new Scanner(System.in);
try {
// 可能出现问题的代码
System.out.print("请输入第一个整数:");
int num1 = input.nextInt();
System.out.print("请输入第二个整数:");
int num2 = input.nextInt();
// 计算除法
int num3 = num1 / num2;
System.out.println(num1+"/"+num2+"="+num3);
}catch(InputMismatchException e) { // 能捕获的异常类型
System.out.println("对不起!请输入整数!");
}
System.out.println("程序结束!");
// 类似于多重if一样,出现的异常会挨个进行尝试调用catch 只要有一个匹配 则执行处理 后面的catch不会处理了
// 小心异常类型范围大的记得放在后面
try{
// 可能出现问题的代码
}catch(异常类型1){
// 对应的处理代码
}catch(异常类型2){
// 对应的处理代码
}.....
catch(Exception e){ // Exception是异常的顶级父类 它可以接收任何异常类型的对象 (多态)
// 最终默认的处理代码
}
Scanner input = new Scanner(System.in);
try {
// 可能出现问题的代码
System.out.print("请输入第一个整数:");
int num1 = input.nextInt();
System.out.print("请输入第二个整数:");
int num2 = input.nextInt();
// 计算除法
int num3 = num1 / num2;
System.out.println(num1+"/"+num2+"="+num3);
}catch(InputMismatchException e) { // 能捕获的异常类型
System.out.println("对不起!请输入整数!");
}catch (ArithmeticException e) {
System.out.println("对不起!除数不能为0!");
}catch (Exception e) {
System.out.println("服务器繁忙!");
}
System.out.println("程序结束!");
Scanner input = new Scanner(System.in);try { // 可能出现问题的代码 System.out.print("请输入第一个整数:");
int num1 = input.nextInt();
System.out.print("请输入第二个整数:");
int num2 = input.nextInt();
// 计算除法
int num3 = num1 / num2; System.out.println(num1+"/"+num2+"="+num3);
// 一般用于多种需要的处理手段一致的情况下会采用
}
catch(InputMismatchException | ArithmeticException e) {
// 能捕获的异常类型
// System.err.println("异常出现了!"+e.getMessage());
e.printStackTrace();
// 打印异常的堆栈跟踪
}System.out.println("程序结束!");
catch代码块中是用于处理异常情况,一般情况下有下方几种手段:
try {
}catch(异常类型 e){
// 处理异常的代码段
}finally{
// 最终执行的的代码段:无论是否出现异常 此处代码段都会被执行
// 一般的应用在资源释放上 io即输入输出 数据以流的形式输入输出
}
try{
// 可能出现的异常的代码
}finally{
// 最终执行的代码:资源释放...
}
面试题1:如果finally和return同时出现,那么如何执行?
会先执行finally中的内容,然后再执行return。
面试题2:final、finally、finalize的区别
final的作用
finally的作用
finalize的作用
它是Object类中的一个方法,是Java的GC(垃圾回收器)自动会调用的一个方法。
用法:protected void finalize() throws Throwable { }
用throw和throws的关键字
throw和throws的区别
throw 表示抛出异常 抛出异常后面要跟随异常的对象,用于告知调用者异常的信息(异常对象)后期常用来抛出自定义异常。
// 摘自:java.util.Scanner.nextInt()方法
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
}
// 数值格式转换异常
catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());// 抛出异常
}
throws表示声明异常,它是在方法声明上进行指定的,一般表示此方法不会异常处理,最终由调用者统一处理。
例如:
public FileInputStream(File file) throws FileNotFoundException;
Throwable顶级接口
// 异常指的是可以经过处理而修复的问题
// 错误是指必须通过修改代码才能修复的问题才能修复的问题
Exception异常的顶级父类 Error错误的顶级父类:
//OutOfMemory StackOverFlow
//check异常(受检异常)表示代码编写出来后必须要求提前处理的异常
//例如:FileNotFoundException
//unchecked/runtimeException 运行异常(不受检异常): 表示代码编写后非必须要求处理的异常
如果觉得java的异常体系不够丰富可以自行创建异常类。.
//public class IllegalAgeException extends Exception{
public class IllegalAgeException extends RuntimeException{
public IllegalAgeException() {
super();
}
public IllegalAgeException(String message) {
super(message);
}
}
public void setAge(int age) throws Exception {
if(age < 0 || age > 100) {
// System.out.println("对不起!年龄非法!");
// throw new Exception("年龄非法!");
throw new IllegalAgeException("年龄非法!");
}else {
this.age = age;
}
}
logforjava
Int2String
try{
}catch(Exception e){
// 处理
}
它用来记录系统运行中的一些重要操作信息,便于监视系统运行情况,也便于出现问题后快速找到原因的文件。
.log
我们要记录日志,如果自己来实现这种功能非常繁琐,所以有很多组织或个人开发了相关的工具开源出来供我们使用,那么在我们的Java项目中如何去引用他们编写的这些工具呢?
步骤:
jar
包(压缩包 字节码文件的集合)我们记录日志可以采用的工具包:log4j、log4j2、logback…(slfj日志门面)
在Java项目中创建一个文件夹(lib)存放jar包
将jar包引入为类库
在jar包上右键 -> build path -> add to build path
根据要求和使用说明进行使用
准备一个日志配置文件log4j.properties
配置日志运行的规则
### 设置Logger输出级别和输出目的地(可以指定多个目的地) ###
### 一般在开发的时候使用debug,开发完成后使用error ###
### 他们对应的是输出信息的级别,级别越低信息输出越详细,使用debug级别的时候,info中的信息也能输出,使用info的时候,debug对应的信息显示不出来 ###
### 日志记录器输出级别:fatal>error>warn>info>debug ###
### 后面的两个对应下方的两处 一处打印在控制台 另一处打印在日志文件里
log4j.rootLogger=debug,console,logFile
##################################################################################
### 把日志信息输出到控制台 ###
log4j.appender.console=org.apache.log4j.ConsoleAppender
### 信息打印到System.err上,红色 ###
log4j.appender.console.Target=System.out
### 指定日志在控制台上输出的布局类型 采用指定格式的类型 ###
log4j.appender.console.layout=org.apache.log4j.PatternLayout
### %r:输出自应用启动到输出该 log信息耗费的毫秒数 %x表示信息输出时左对齐
### %5p:%p表示输出日志信息优先级,即 DEBUG, INFO, WARN, ERROR, FATAL 中间的5控制最小的宽度为5
### %F:%L %F:输出日志消息产生时所在的文件名称 %L:输出代码中的行号
### %l:输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及行数
### %m:输出代码中指定的消息,产生的日志具体信息 %n:输出一个回车换行符, Windows 平台为"\r\n", Unix 平台为"\n"输出日志信息换行
log4j.appender.console.layout.ConversionPattern= (%r ms) - %d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
##################################################################################
#################################################################################
### 把日志信息输出到文件:jbit.log 注意:如果有路径\符号一定要写成\\ 否则会被转义 ###
log4j.appender.logFile=org.apache.log4j.FileAppender
### 指定日志输出的文件名 ###
log4j.appender.logFile.File=test.log
### 指定转换模式 ###
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
### 指定日志布局类型 ###
###log4j.appender.logFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l %F %p %m%n
###log4j.appender.logFile.layout.ConversionPattern= -> (%r ms) - %d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
log4j.appender.logFile.layout.ConversionPattern= (%r ms) - %d{yyyy-MM-dd HH:mm:ss}%x[%5p]%l %m%n
#################################################################################
使用API来进行日志记录
Logger类
Logger getLogger(字节码对象);
public class Demo1 {
// 类名.class
static Logger logger = Logger.getLogger(Demo1.class);
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
try {
logger.info(">>>>>>程序启动>>>>>>>");
// 可能出现问题的代码
System.out.print("请输入第一个整数:");
int num1 = input.nextInt();
logger.info(">>>>>用户正在输入第一个整数,输入的数值为:"+num1+">>>>>>>>");
System.out.print("请输入第二个整数:");
int num2 = input.nextInt();
logger.info(">>>>>用户正在输入第二个整数,输入的数值为:"+num2+">>>>>>>>");
// 计算除法
int num3 = num1 / num2;
logger.info(">>>>>用户正在进行结果计算,结果为:"+num3+">>>>>>>>");
System.out.println(num1+"/"+num2+"="+num3);
}catch(InputMismatchException e) { // 能捕获的异常类型
logger.error(">>>>>>>程序出现输入不匹配异常>>>>>>",e);
}catch (ArithmeticException e) {
logger.error(">>>>>>>程序出现算术异常>>>>>>",e);
}catch (Exception e) {
logger.error(">>>>>>>程序出现未知异常>>>>>>",e);
}
System.out.println("程序结束!");
logger.info(">>>>>>程序结束>>>>>>>");
}
}
="+num3);
}catch(InputMismatchException e) { // 能捕获的异常类型
logger.error(">>>>>>>程序出现输入不匹配异常>>>>>>",e);
}catch (ArithmeticException e) {
logger.error(">>>>>>>程序出现算术异常>>>>>>",e);
}catch (Exception e) {
logger.error(">>>>>>>程序出现未知异常>>>>>>",e);
}
System.out.println(“程序结束!”);
logger.info(">>>>>>程序结束>>>>>>>");
}
}
```