异常/错误
程序运行过程中,可能会发生一些不被期望的效果,肯定会阻止我们的程序按照指令去执行。这种不被预期出现的效果,肯定需要抛出来告诉我们,在Java中有一个定义好的规则Throwable,它是所有异常和错误的父类。
异常和错误一旦发生且没有得到相应处理,程序就会中断执行。
Error错误
通常是一些物理性的,JVM虚拟机本身出现的问题,程序指令是处理不了的。
常见的错误有:
StackOverflowError
:栈内存溢出
OutOfMemoryError
堆内存溢出
Exception异常
通常是一种人为规定的不正常的现象,通常是给定的程序指令产生了一些不符合规范的事情。
异常可以分为:
编译时异常和运行时异常。
运行时异常
通常我们认为Error和RuntimeException都算作运行时异常。
运行时异常也叫做非检查异常,是在javac编译的时候,不会提示和发现的,在程序编写时不要求必须做处理,如果我们愿意可以添加处理手段(try-catch / throws)
常见的运行时异常:
InputMisMatchException
输入不匹配
int value = input.nextInt();// abcNumberFormatException
数字格式化异常
int value = Integer.parseInt(“123.45”);NegativeArraySizeException
数组长度负数
int[] array = new int[-2];ArrayIndexOutOfBoundsException
数组索引越界
int[] array = {1,2,3};
array[5];NullPointerException
空指针异常
int[][] array = new int[3][];
array[0][0] =10;
Person p = null;
p.getName();ArithmeticException
数字异常
10/0 整数不允许除以0 Infinity小数除以0会产生无穷ClassCastException
造型异常
Person p = new Teacher();
Student s = (Student)p;StringIndexOutOfBoundsException
字符串越界
String str = “abc”;
str.charAt(5);IndexOutOfBoundsException
集合越界
List家族
ArrayList list = new ArrayList();
list.add(); list.add(); list.add();
list.get(5);IllegalArgumentException
非法参数异常
ArrayList list = new ArrayList(-1);
编译时异常
编译时异常是指除Error和RuntimeException以外其他异常,也叫做检查异常。
在javac编译的时候,强制要求我们必须为这样的异常做处理(try-catch或throws),因为这样的异常在程序运行过程中极有可能产生问题的。
编译时异常是Exception大家族中很庞大的体系分支,只要不属于运行时异常的都属于编译时异常。
举例:InterruptException
try{
Thread.sleep(5000);
}catch(InterruptException e){
}
异常处理的两种手段
try{}catch(){}[ finally{} ]
- try不能单独的出现
- 后面必须添加catch或finally
- catch有一组括号 (NullPointerException) 目的是为了捕获某一种异常
- catch可以存在很多个
- 捕获的异常之间没有任何的继承关系
- 捕获的异常需要从小到大进行捕获
- finally不是必须存在的
若存在finally结构 则必须执行
引申一个小问题:
final finally finalize区别?
-
final 是特征修饰符 修饰变量 属性 方法 类
修饰变量: 如果修饰的基本类型,值不能改变 。如果修饰的引用类型,则地址不能改变(如果变量没有初值 给一次机会赋值)
修饰属性:特点与修饰变量类似 (要求必须给属性赋初始值 否则编译报错)
修饰方法:不能被子类重写
修饰类:不能被其他的子类继承 -
finally 是处理异常手段的一部分
try{}catch(){}后面的一个部分
这个部分可有可无 如果有只能含有一份 且必须执行 -
finalize 是Object类中的一个protected修饰的方法
对象没有任何引用指向的时候 – 会被GC回收
当对象回收的时候 默认调用finalize方法
若想要看到对象回收的效果 可以重写 public void finalize(){}
处理异常放在方法内部 可能还会有小问题
如果在方法内部含有返回值
不管返回值return关键字在哪里 finally一定会执行完毕
返回值的具体结果 看情况(有没有出现异常)
throws抛出
- 异常只能在方法上抛出 属性是不能抛出异常的
- 方法,构造方法都可以抛出异常,块不行
- 方法可以抛出不止一个异常 通过逗号隔开
- 抛出的异常与多个catch类似,要么没关系(并列的), 要么先抛出小异常,再抛出大异常
自定义异常
自定义运行时异常:
继承RuntimeException类
public class MyRuntimeException extends RuntimeException{
}
自定义编译时异常:
继承Exception类
public class MyException extends Exception{
}
还可以给自定义异常添加异常信息描述的功能:
public class MyRuntimeException extends RuntimeException{
public MyRuntimeException(){}
public MyRuntimeException(String msg){
super(msg);
}
}