Error:严重错误
Exception —— 可以解决的
一、运行时异常/未检查异常:RuntimeException -> Exception
ClassCastException:类型转换异常
NullPointerException:空指针异常
ArrayIndexOutOfBoundsException:数组越界异常
xxxIndexOutOfBoundsException
ConcurrentModificationException:集合迭代删除异常
NumberFormatException:数值转换异常 eg.Integer.valueOf(“aa”);
ArithmeticException: /by zero
造成原因: 程序员自身马虎,必须要解决
二、已检查异常:Exception
FileNotFoundException
IOException
ParseException
SQLException
UnsupportedEncodingException
ClassNotFoundException
造成原因: 不是程序员自身问题,没办法完全避免的异常;
可能是外部客观原因,不能彻底解决,只能避免
三、处理异常
只有已检查异常必须用代码处理,未检查异常必须修改代码、纠正程序
- 方法上声明抛出throws已检查异常
- 自己处理 try/catch代码块
注意:
try只能有一个,catch可以有多个,至少有一个
一个catch可以捕获多个异常,用 | 连接
同一个异常不能多次捕获
捕获异常,可以使用父类异常捕获
如果同时捕获子类和父类,必须先捕获子类异常再捕获父类异常
try不能独立使用
try-catch可以嵌套但是不推荐
e.printStackTrace():打印代码执行栈路径,通常开发调试时会保留,上线时删除
finally:无论如何都会执行的,通常用来释放资源
throw:手动抛出异常对象
异常处理原则: 能解决的尽量自己解决,不能解决了再往外抛
异常属性: message - 异常提示信息,很重要。所有异常都有一个使用message初始化 的构造器,所有异常都有getMessage
自定义异常: 目的:为了区分不同的异常类型。定义方法:只需要添加构造器即可,其它全靠继承
四、面试题
(1)throw和throws区别
- 区别:throws是用来声明一个方法可能抛出的所有异常信息,它将异常声明但是不处理,只是往上抛,谁调用就交给谁来处理;而throw则是指抛出一个具体的异常类型
- 分别介绍
throws: 用于声明异常,例如,一个方法里面不想有任何的异常处理,则在没有任何代码进行异常处理的时候,必须对这个方法进行声明有可能产生的所有异常类型
格式:方法名(参数) throws 异常类1 异常类2……
throw: 就是自己进行异常处理,处理的时候有两种方式,要么自己捕获异常(try catch),要么声明抛出一个异常(throw 异常类)
注意:
throw一旦被执行,程序会立即转入异常处理阶段,后面的语句就不再执行,而且所在的方法不再返回有意义的值。
(2)final、finally、finalize
- final 可以用来修饰类、方法和变量(局部变量或成员变量)
a.修饰类:当用final修饰类时,表示该类不能被其他类所继承。当我们需要一个类永远不被继承时,就可以用final修饰,但需注意:final类中所有的成员方法都会隐式地定义为final方法
b.修饰方法:方法不能被重写
c.修饰变量:当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象了,但该引用所指向的对象的内容是可以发生变化的。本质上是一回事,因为引用的值是一个地址,final要求值,即地址的值不发生变化。
final修饰一个成员变量(属性),必须要显示初始化。这里有两种初始化方式,一种是在变量声明的时候初始化;第二种方法是在声明变量的时候不赋初值,但是要在这个变量所在的类的所有的构造函数中对这个变量赋初值。
当函数的参数类型声明为final时,说明该参数是只读型的。即你可以读取使用该参数,但是无法改变该参数的值。 - finally 在java语句的异常处理中,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会被执行,由于程序执行return就意味着结束对当前函数的调用并跳出这个函数体,因此任何语句要执行都只能在return语句之前(除非碰到exit函数),因此finally块里的代码也是在return之前执行的,此外,如果try-finally或者catch-finally中都有return,那么finally块中的return将会覆盖别处的return语句,最终返回到调用者那里的是finally语句中的return值。
- finalize finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。
特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。
使用finalize还需要注意一个事,调用super.finalize();