1、try{} 里有一个 return 语句,那么紧跟在这个 try 后的 finally{} 里的 code 会不会被执行,什么时候被执行,在 return 前还是后?
会被执行,在try…catch语句中,当程序执行完return后的表达式后,会转而执行finally语句块,最后再继续执行return
2、Java语言如何进行异常处理,关键字:throws、throw、try、catch、finally分别如何使用?
3、列出一些你常见的运行时异常?
1、异常处理
语法错误:编译器可以检查出来的,不是异常;
异常:在程序运行期间发生的错误(意外情况);一般都是:逻辑问题、数据问题、硬件问题、资源问题。
1.1 异常处理的目的:
防止程序中途退出
发生异常不处理 则会中断程序
发生异常 处理异常 程序正常运行
1.2异常的分类
Throwable:顶级的父类型
Error:错误,一般是由JVM引发的错误,系统操作引发的错误,无法通过编码进行解决。
public class Error extends Throwable
Exception:异常
编译时异常:(checked检查异常);编码时必须处理的异常,一般可以预料到
运行时异常:(unchecked非检查异常):RuntimeException,运行过程中发生的错误;
常见的运行时的异常:
//NullPointerException:对象没有赋值(null) //ArithmeticException:算术异常; //ClassCastException:类型转化异常 //ArrayIndexOutOfBoundsException:数组下标越界 //IllegalArgumentException
如何进行异常处理
处理方式:
1、使用try...catch:处理异常
2、使用throw,throws,抛出异常;
异常关键字:
try: 尝试,监视;监视:可能发生异常的代码;
catch: 捕获,捕捉;
finally: 最后,最终
throw: 动词:抛出
throws:名词:声明可能抛出的异常类型
1、使用try...catch...进行异常处理
2、使用try...catch...finally处理
public static void main(String[] args) { Scanner scanner=new Scanner(System.in); try{ //可能发生异常的代码 System.out.println("请输入第一个操作数:"); int num1=scanner.nextInt(); System.out.println("请输入第二个操作数:"); int num2=scanner.nextInt(); System.out.println("除法运算:"+num1/num2); //释放资源:一旦发生异常会导致资源无法释放 }catch (Exception e){ //捕获异常: 将异常的信息封装到异常对象:e中 //打印异常的堆栈信息 // e.printStackTrace(); //返回异常的信息 System.out.println("发生了异常:"+e.getMessage()); }finally {//无论任何情况,一定会执行 // 释放资源 System.out.println("最后执行的代码"); } System.out.println("程序正常运行"); }
3、多重catch
特点:发生异常时,catch只会执行一个;
catch异常的顺序:先子类异常,再父类异常;
public static void main(String[] args) { Scanner scanner=new Scanner(System.in); try{ //可能发生异常的代码 System.out.println("请输入第一个操作数:"); int num1=scanner.nextInt(); System.out.println("请输入第二个操作数:"); int num2=scanner.nextInt(); System.out.println("除法运算:"+num1/num2); //释放资源 }catch (InputMismatchException ex){ System.out.println("输入异常:"+ex.getMessage()); }catch(ArithmeticException ex) { System.out.println("算术异常:"+ex.getMessage()); }catch (RuntimeException ex){ System.out.println("其它异常:"+ex.getMessage()); } finally {//无论任何情况,一定会执行 // 释放资源 System.out.println("最后执行的代码"); } System.out.println("程序正常运行"); }
4、try...finally结构
public static void main(String[] args) { Scanner scanner=new Scanner(System.in); try{ //可能发生异常的代码 System.out.println("请输入第一个操作数:"); int num1=scanner.nextInt(); System.out.println("请输入第二个操作数:"); int num2=scanner.nextInt(); System.out.println("除法运算:"+num1/num2); //释放资源 }finally {//无论任何情况,一定会执行 // 释放资源 System.out.println("最后执行的代码"); } System.out.println("程序正常运行"); }
使用throw抛出异常:
示例1:除法运算
public class Calc { public static int div(int a,int b){ if(b!=0){ return a/b; }else{ //不符合业务逻辑,需要抛出异常 throw new ArithmeticException("除数不能是0"); // System.out.println(""); } } }
示例2:性别检查
public class User { private String name; private char sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public char getSex() { return sex; } public void setSex(char sex) { if(sex!='男'&&sex!='女'){ throw new RuntimeException("性别不能是其它的"); } this.sex = sex; } }
检查年龄,检查身份证号;
使用throws声明可能抛出的异常
//如果在代码中throw检查异常(编译时异常),方法上必须使用throws // throws:用在方法后面,声明该方法可能抛出的异常类型,多类型用,隔开,只会抛出一个 public static int div(int a,int b) throws Exception { if(b!=0){ return a/b; }else{ //不符合业务逻辑,需要抛出异常 throw new Exception("除数不能是0"); // System.out.println(""); } }
自定义异常
目的:满足的业务规则;
步骤:
1、创建一个类 继承自 异常类型(Exception, RuntimeException)
2、调用构造方法进行信息的初始化
public class SexException extends RuntimeException { public SexException(String message) { super(message); } } public void setSex(char sex) { if(sex!='男'&&sex!='女'){ // throw new RuntimeException("性别不能是其它的"); throw new SexException("性别不能是男女之外的"); } this.sex = sex; }
调用时进行异常处理:
public static void main(String[] args) { // int a=Calc.div(10, 0); // System.out.println(a); User user=new User(); try { user.setSex('中'); } catch (SexException e) { e.printStackTrace(); } System.out.println(user.getSex()); }
2、使用log4j记录日志
日志?
1、记录系统中的操作流程
2、便于发现过程中错误
如何记录日志:
使用步骤:
1、引入jar包
2、在src根目录下:配置log4j.properties文件(配置文件)
存放的是:键值对
### 把日志信息输出到控制台 ### #stdout:本组配置的名称,自定义 #org.apache.log4j.ConsoleAppender:完全限定的类名,输出到控制台 log4j.appender.stdout=org.apache.log4j.ConsoleAppender #Target:目标 log4j.appender.stdout.Target=System.out #layout: 输出数据的格式类型 :PatternLayout:自定义格式 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %m %M %n ### 把日志信息输出到文件:Anbo.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=demo10.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
3、在程序中使用
### 把日志信息输出到控制台 ### 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=Anbo.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=debug, stdout, file
PatternLayout:自定义输出格式的常用参数: %d:用来设置输出日志的日期和时间格式,默认格式为IS08601,也可以自定义格式,例如%d{yyyy-MM-dd HH : mm : ss},输出格式类似于2010-03-0917 : 51。 %m:用来输出代码中设置的异常提示信息。 %n:用来输出一个回车换行符。 %I:用来输出日志事件的发生位置,包括类名、发生错误的行号等信息。 %F:用来输出文件名。 %M:用来输出方法名。
方法列表public void fatal(Object msg):致命的错误public void error(Object msg):错误public void warn(Object msg):警告public void info(Object msg):信息public void debug(Object msg):调试