Java可抛出
(Throwable)
的结构分为三种类型:
被检查的异常
(CheckedException)
,
运行时异常
(RuntimeException)
,
错误
(Error)
。
1
、运行时异常
定义:
RuntimeException
及其子类都被称为运行时异常。
特点:
Java
编译器不会检查它。也就是说,当程序中可能出现这类异常时,倘若既
"
没有通过
throws
声明抛出它"
,也
"
没有用
try-catch
语句捕获它
"
,还是会编译通过。例如,除数为零时产生的
ArithmeticException
异常,数组越界时产生的
IndexOutOfBoundsException
异常,
fail-fast
机制产生的 ConcurrentModificationException异常(
java.util
包下面的所有的集合类都是快速失败的,
“
快速失败
” 也就是fail-fast
,它是
Java
集合的一种错误检测机制。当多个线程对集合进行结构上的改变的操作时,有可能会产生fail-fast
机制。记住是有可能,而不是一定。例如:假设存在两个线程(线程
1
、线程
2
),线程1
通过
Iterator
在遍历集合
A
中的元素,在某个时候线程
2
修改了集合
A
的结构(是结构上面的修改,而不是简单的修改集合元素的内容),那么这个时候程序就会抛出 ConcurrentModificationException
异常,从而产生fail-fast
机制,这个错叫并发修改异常。
Fail-safe
,
java.util.concurrent
包下面的所有的类都是安全失败的,在遍历过程中,如果已经遍历的数组上的内容变化了,迭代器不会抛出ConcurrentModificationException异常。如果未遍历的数组上的内容发生了变化,则有可能反映到迭代过程中。这就是ConcurrentHashMap
迭代器弱一致的表现。
ConcurrentHashMap
的弱一致性主要是为了提升效率,是一致性与效率之间的一种权衡。要成为强一致性,就得到处使用锁,甚至是全局锁,这就与Hashtable
和同步的
HashMap
一样了。)等,都属于运行时异常。
常见的五种运行时异常:
ClassCastException
(类 转 换 异 常 )
IndexOutOfBoundsException
(数组越界)
NullPointerException
(空指针异常)
ArrayStoreException
(数据存储异常,操作数组是类型不一致)
BufferOverflowException
2
、被检查异常
定义:
Exception
类本身,以及
Exception
的子类中除了
"
运行时异常
"
之外的其它子类都属于被检查异常。
特点 :
Java
编译器会检查它。 此类异常,要么通过
throws
进行声明抛出,要么通过
try-catch
进行捕获
处理,否则不能通过编译。例如,CloneNotSupportedException
就属于被检查异常。
当通过
clone()
接口去克隆一个对象,而该对象对应的类没有实现
Cloneable
接口,就会抛出
CloneNotSupportedException
异常。被检查异常通常都是可以恢复的。 如:
IOException
FileNotFoundException
SQLException
被检查的异常适用于那些不是因程序引起的错误情况,比如:读取文件时文件不存在引发的FileNotFoundException 。然而,不被检查的异常通常都是由于糟糕的编程引起的,比如:在对象引用时没有确保对象非空而引起的NullPointerException
。
3
、错误
定义
: Error
类及其子类。
特点
:
和运行时异常一样,编译器也不会对错误进行检查。
当资源不足、约束失败、或是其它程序无法继续运行的条件发生时,就产生错误。程序本身无法修复这些错误的。例如,VirtualMachineError
就属于错误。出现这种错误会导致程序终止运行。
OutOfMemoryError
、
ThreadDeath
。
Java
虚拟机规范规定
JVM
的内存分为了好几块,比如堆,栈,程序计数器,方法区等