异常处理:
Java异常处理的关键字有:try catch finally throw throws
错误不是异常,而是脱离程序员控制的问题,所有的异常类是从java.lang.Exception类继承的子类。
异常发生的原因通常包含:
用户输入了非法的数据
要打开的文件不存在
网络通信时连接中断,或者JVM内存的溢出。
try catch结构的语法:
public classTest {public static voidmain(String[] args) {try{
Scanner in= newScanner(System.in);
System.out.print("请输入被除数:");int num1 =in.nextInt();
System.out.print("请输入除数:");int num2 =in.nextInt();
System.out.println(String.format("%d / %d = %d", num1, num2, num1/num2));
System.out.println("感谢使用本程序!");
}catch(Exception e) {
System.err.println("产生了异常信息"+e.getMessage());//e.getMessage()获得异常部分信息
}
System.out.println("try catch块后面的代码");
}
}
需要注意的是,在上例中,当除数为0时,程序会产生异常。此时try catch块后面的代码会正常输出。程序运行结果为:
请输入被除数:2请输入除数:0产生了异常信息/by zerotry catch块后面的代码
e.getMessage()为获得异常部分信息。即在本例中输出的是:/ by zero
try与catch与finally结构
public static voidmain(String[] args) {try{
Scanner in= newScanner(System.in);
System.out.print("请输入被除数:");int num1 =in.nextInt();
System.out.print("请输入除数:");int num2 =in.nextInt();
System.out.println(String.format("%d / %d = %d", num1, num2, num1/num2));
System.out.println("感谢使用本程序!");
}catch(Exception e) {
}finally{
System.out.println("这里是finally块");
}
}
需要注意的是,唯一不运行finally的情况就是退出JVM,即System.exit(0); 当catch语句里有return时,先运行finally,最后执行return语句。finally不管是否产生异常,都会执行其中的代码。上例中运行结果为:
请输入被除数:4请输入除数:0这里是finally块
多重try catch块
多重try catch块有以下特征:排列catch语句的顺序:先子类后父类;发生异常时按照顺序逐个匹配;只执行第一个与异常类型匹配的catch语句。语法结构为:
try{//程序代码}catch(异常类型1异常的变量名1){
//程序代码}catch(异常类型2异常的变量名2){
//程序代码}catch(异常类型2异常的变量名2){//程序代码
}
throws/throw关键字
如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。下个实例中,抛出了一个RemotException异常,一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
public classclassName
{public void deposit(double amount) throwsRemoteException
{throw newRemoteException();
}
}
处理异常时有以下注意事项:catch 不能独立于 try 存在。在 try/catch 后面添加 finally 块并非强制性要求的。try 代码后不能既没 catch 块也没 finally 块。try, catch, finally 块之间不能添加任何代码。
记忆:(常见的异常类型)
Exception:异常层次结构的父类
ArithmeticException:算术错误情形,如以零作除数
ArrayIndexOutOfBoundsException:数组下标越界
NullPointerException:尝试访问null对象成员
ClassNotFoundException:不能加载所需的类
IIIegalArgumentException:方法接收到非法参数
ClassCastException:对象强制;类型转换出错
NumberFormatException:数字格式转换异常,如把“abc”转换成数字
日志
需要先导入一个Jar包,以下实例为创建一个日志对象,然后存放异常信息并显示到控制台:
public static voidmain(String[] args) {//创建一个日志对象
Logger logger=Logger.getLogger("测试类Test");
Scanner input=newScanner(System.in);try{
System.out.println("请输入被除数");int a =input.nextInt();
System.out.println("请输入除数");int b =input.nextInt();
System.out.println("结果:" + a /b);
}catch(ArithmeticException e) {//日志存放错误信息
logger.debug(" 除数不能为0");
}catch(Exception e) {//日志存放错误信息
logger.debug(" 输入的不是数字");
}
}
log4j.properties配置文件源码为:
### 设置Logger输出级别和输出目的地 ###
log4j.rootLogger=debug, stdout,logfile
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p %d{yyyy-MM-dd HH:mm:ss SSS} %l%m%n
### 把日志信息输出到文件:jbit.log ###
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=jbit.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
输出结果为:
请输入被除数54请输入除数0DEBUG2018-03-28 19:11:08 639 com.log.Test.main(Test.java:21) 除数不能为0
日志文件会实时记录异常信息:
2018-03-28 17:31:04com.log.Test.main(Test.java:25) Test.java DEBUG 输入的不是数字2018-03-28 18:18:39com.log.Test.main(Test.java:21) Test.java DEBUG 除数不能为02018-03-28 19:11:08com.log.Test.main(Test.java:21) Test.java DEBUG 除数不能为02018-03-28 19:11:56com.log.Test.main(Test.java:21) Test.java DEBUG 除数不能为0