异常
分为两大类:
错误(Error):JVM系统内部错误、资源耗尽等严重情况;
- VirtualMachineError
- LinkageError
- ……
违例(Exception):其他因变成错误或偶然外在因素导致的一般性问题,例如对负数开平方根,空指针访问、试图读取不存在的文件以及网络中断等。
- RuntimeException(uncheck exception,代码中不需要捕获处理:错误的类型转换,数组下标越界,空指针访问……)
- IndexOutOfBoundsException
- NullPointerException
- ArithmeticException
- ……
- IOException(check excepiton,违例需要捕获:从不存在的文件中读数据,越过文件结尾继续读取,连接不存在的URL…..)
- FileNotFoundException
- EOFException
- ……
- ……
- RuntimeException(uncheck exception,代码中不需要捕获处理:错误的类型转换,数组下标越界,空指针访问……)
其中RuntimeException + Error 和其子类都是属于uncheck exception;Exception类中除了RuntimeException之外的类,都是属于check exception
违例的处理方式
- 方式一:try…catch…;
方式二:声明抛弃异常 throws [Exception],此时不对此类异常进行处理,由该方法的调用者负责处理。
public class TestException { // throws方式处理异常 public static void main(String[] args) throws IOException { System.out.println(System.getProperty("user.dir")); FileWriter writer = new FileWriter("helloworld.txt"); writer.write("您好,世界!"); writer.close(); // try...catch方式处理异常 try { File file = new File("helloworld.txt"); InputStream stream = new FileInputStream(file); int length = 0; byte[] buffer = new byte[1024]; while (-1 != (length = stream.read(buffer))) { System.out.println(new String(buffer, 0, length)); } stream.close(); FileReader reader = new FileReader(file); char[] chars = new char[1024]; while (-1 != (length = reader.read(chars))) { System.out.println(new String(chars, 0, length)); } reader.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("run in finally"); } } }
重写方法声明抛弃异常
重写方法不允许抛出比被重写方法范围更大的异常类型class A { public void ma() throws IOException { } } class B1 extends A { // 重写基类方法,抛出的异常范围更小 @Override public void ma() throws FileNotFoundException, EOFException { } } class B2 extends A { // 重写基类方法,不允许抛出范围更大的异常 @Override public void ma() throws Exception { //非法 } }
用户自定义异常
- 被抛出的必须是Throwable或其子类对象
public class TestMyException {
public static void main(String[] args) {
try {
// 主动抛出异常
throw new MyException("失败信息", 3);
} catch (MyException e) {
System.out.println(e.getMessage());
}
}
}
class MyException extends Exception {
private static final long serialVersionUID = 1L;
private int idNumber;
public MyException(String message, int id) {
super(message);
this.idNumber = id;
}
public int getIdNumber() {
return idNumber;
}
}
断言(Assert)
- 断言机制在用户定义的boolean表达式(判定条件)为false时跑出一个Error对象,类型为
AssertionError
- 在约定条件不成立时,要中断当前操作,可以使用断言
- 作为Error的一种,断言失败不需要捕获处理或声明抛出,一旦出现了则终止程序
Java运行时环境默认设置为关闭断言功能,使用前要打开断言功能:
// 开启断言 java -ea MyAppClass java -enableassertions MyAppClass // 关闭断言 java -da MyAppClass java -disableassertions MyAppClass
Eclipse中开启java的assert选项 https://my.oschina.net/styshoo/blog/546681
两种使用assert的方式:
方式一:
assert age > 0;
方式二:
assert (age > 0) : "年龄必须是正整数";
代码样例:
public class TestAssert {
private int age = 0;
public void setAge(int age) {
// 设置断言
assert (age > 0) : "年龄必须是正整数";
this.age = age;
System.out.println("设置年龄成功");
}
public static void main(String[] args) {
TestAssert testAssert = new TestAssert();
testAssert.setAge(-18);
}
}
开启-ea
断言功能,运行结果:
Exception in thread "main" java.lang.AssertionError: 年龄必须是正整数
at com.github.rayluoluo.snippet.s15testassert.TestAssert.setAge(TestAssert.java:13)
at com.github.rayluoluo.snippet.s15testassert.TestAssert.main(TestAssert.java:20)