概述
空指针异常
int[] arr = null;
System.out.println(arr[2]);
String str = "aaa";
str = null;
System.out.println(str.charAt(0));
数组越界
NumberFormatException
输入不匹配异常
ArithmeticException
以上是运行时异常
上面是编译时异常,即javac的时候就会报错。
异常处理方式
try catch
以例子来说明:
public class ExceptionTest {
public static void main(String[] args) {
String str = "abc123";
int num = Integer.parseInt(str);
System.out.println(num);
}
}
会报错:(NumberFormatException.java:68)
但我们使用异常处理:
public class ExceptionTest {
public static void main(String[] args) {
String str = "abc123";
try {
int num = Integer.parseInt(str);
}catch (NumberFormatException e){
System.out.println("待转换字符串中有非数字字符!");
}
System.out.println("end...");
}
}
运行结果:
待转换字符串中有非数字字符!
end...
说明:
- 注意,只有catch后面的异常是try里可能发生的异常时才不会报错,类似switch case。
- finally可以不写
- 当执行一条catch之后,就不会执行其他的catch
- 把范围大的异常catch放后面,不然范围小的异常将永远不会执行。
- try里面声明的变量,在外面不能使用(似乎在catch里也不能用?)
finally
finally里面的语句一定会被执行:
public static int method() {
try {
int[] arr = new int[10];
System.out.println(arr[10]);
return 1;
}catch(ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
return 2;
}finally {
System.out.println("我一定会执行!");
return 3;
}
}
我们调用这个方法,结果是:
但要注意,finally中应避免出现return:https://blog.csdn.net/chh_jiang/article/details/4557461
什么时候用finally呢?
比如说下图,fis创建成功了,但在read的时候出现了异常,那么就会跑到catch处执行而把close()跳过,导致文件不能关闭。
try catch finally 总结
throws
https://www.bilibili.com/video/BV1Kb411W75N?p=378
子类重写方法与异常
子类如果重写了父类的方法,且子类抛出异常的话,这个异常的范围一定小于等于父类抛出异常的范围,原因如下:
import java.io.FileNotFoundException;
import java.io.IOException;
public class OverrideTest {
public static void main(String[] args) {
OverrideTest o = new OverrideTest();
o.test(new SubClass());
}
public void test (SuperClass s) {
try {
s.method();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class SuperClass {
public void method() throws IOException{
}
}
class SubClass extends SuperClass {
public void method() throws FileNotFoundException {
}
}
分析:由于test方法使用了多态,那么当传入一个SubClass类型的对象时,会执行被重写的method方法,这个被重写的方法有可能抛出异常,并被test中的try检测到,如果子类的异常类型大于父类,那岂不是说儿子抛出异常到父类,后者却无法解决了吗?所以子类重写方法的异常类型一定小于等于父类。
此外,如果父类中被重写的方法没有throws方式处理异常,那么子类重写的方法也不能用throws,必须要用try/catch形式。
使用try catch finally还是throws?
手动抛出异常对象
有的时候我们并不是要在程序出错时才抛出异常,当用户输入的数据不对时也可以抛出异常(例如,年龄输入的是负数):
public class ShouDongPaoChu {
public static void main(String[] args) {
Student s = new Student();
try {
s.create(-10);
System.out.println(s);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
class Student {
private int age;
public void create(int age) throws Exception {
if (age > 0) {
this.age = age;
}
else {
throw new Exception("输入有误");
}
}
@Override
public String toString() {
return "Student [age=" + age + "]";
}
}
如果我们不自己抛出异常而是直接弄个输出语句,那么age还是会有值(0),但手动抛出异常后就不会了。
自定义异常
throw和throws
前者是声明一个异常对象,后者是异常处理的一种方式。
练习
有一个项目,等以后补吧…