学习代码
https://github.com/starrQWQ/java_code/tree/master/javaSE基础
98 异常概述
java用类来模拟异常
异常发生时,JVM会创建一个异常对象,该对象包含异常信息,JVM将信息输出到控制台。
异常代码之后的代码不会执行,直接退出JVM。
异常机制作用:
通过异常信息完善程序,使程序更加健壮。
99异常继承结构
所有异常都是可抛出的(Throwable)
Error不可处理
Exception可处理,若没有处理则退出JVM。
所有Exception的直接子类都是编译时异常,发生几率高,比如: java.io.IOException
编译时异常要求程序员在编写时处理,否则编译不能通过。处理方法有两种,捕捉(try…catch…)和声明(throws)
protected void finalize() throws Throwable { }
RuntimeException的子类都是运行时异常,编写阶段不需处理。
100-101 throws关键字
在声明方法的地方使用
java编译器不智能。若使用的类的构造方法使用了throw,则必须对其进行捕获或声明以便抛出
import java.io.*;
public class T{
//public static void main(String[] args) throws FileNotFoundException{
//public static void main(String[] args) throws IOException{
public static void main(String[] args) throws IOException{
FileInputStream fis = new FileInputStream("1.txt");
}
}
throws没有真正处理异常,只是推卸责任,谁调用抛给谁。
import java.io.*;
public class T{
public static void main(String[] args) throws IOException{
m1();
}
public static void m1() throws IOException{
m2();
}
public static void m2() throws IOException{
m3();
}
public static void m3() throws IOException{
new FileInputStream("1.txt");
}
}
真正处理应该用try…catch…
实在处理不了才使用throws
102 try…catch…
try{
}catch{异常类型 变量
}catch{
}
try{
FileInputStream fis = new FileInputStream("1.txt");
fis.read();
}catch(FileNotFoundException e){ //细致
}catch(IOException e){ //宽泛
}
try{
FileInputStream fis = new FileInputStream("1.txt");
System.out.println(1); //不执行
fis.read();
}catch(IOException e){
System.out.println(e); //toString()被重写
}catch(FileNotFoundException e){
}
JVM创建异常类型对象,将地址赋给e.
public static void catch(Exception e){}
自上而下执行,第二个catch不会捕获到。
所以,catch可以写多个,但必须从上到下,从小到大。
捕捉到一个异常后语句就结束。
103 getMessage()和printStackTrace()
java.lang.Throwable的两个方法——>所有异常类都有
try{
FileInputStream fis = new FileInputStream("1.txt");
fis.read();
}catch(FileNotFoundException e){
e.printStackTrace(); //更详细
/* 或者
String msg = e.getMessage();
System.out.println(msg);
*/
}
查看源码,根据FileNotFoundException父类型往上找,java.lang.Throwable里找到getMessage(),源码显示信息存储在detailMessage变量里。
104 finally
try…finally (结合throws)
try…catch…finally
try{
//退出JVM
System.exit(0);
}finally{
//不会执行
}
public class _finally{
public static void main(String[] args){
int i = m1();
System.out.println(i);
}
static int i = 10;
public static int m1(){
try{
return i;
}finally{
i++;
System.out.println(i);
}
}
}
为保证某资源一定释放,一般在finally语句块中释放资源。
import java.io.*;
public class Finally1{
public static void main(String[] args){
FileInputStream fis = null;
try{
fis = new FileInputStream("2.txt");
}catch(FileNotFoundException e){
e.printStackTrace();
}finally{
if(fis != null){
try{
fis.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
105 final,finalize,finally(重点)
78,final。
87,finalize是方法名,gc自动调用。
finally是异常机制语句。
106手动throw抛出异常
自定义异常:
编译时异常,直接继承Exception.
运行时异常,直接继承RuntimeException.
定义一般提供两个构造方法。
手动抛出的本意是让程序员知道异常,不需要catch,需要throws.
注意throw和throws的区别。
要清除什么时候catch,什么时候throws.
catch:不想让程序知道。
throws:想让程序知道。
public class IllegalNameException extends Exception{
public IllegalNameException(){}
public IllegalNameException(String msg){
super(msg);
}
}
public class CustomerService{
public void register(String name) throws IllegalNameException{
if(name.length()<6){
/*
IllegalNameException e = new IllegalNameException("name length too short.");
*/
throw new IllegalNameException("name length too short.");
}
System.out.println("register successfully.");
}
}
public class T{
public static void main(String[] args){
String name = "assdfasdf";
CustomerService cs = new CustomerService();
//use catch , otherwise the belowing code will stop.
try{
cs.register(name);
}catch(IllegalNameException e){
System.out.println(e.getMessage());
}
}
}
107 方法覆盖重写异常
重写的方法不能比被重写的方法抛出更宽泛的异常。
子类不能抛出比父类更多的异常。
import java.io.*;
/*
class A{
public void m1(){}
}
class B extends A{
public void m1() throws Exception{}
}
//error
*/
class C{
public void m2() throws FileNotFoundException{}
//public void m2() throws IOException{}
}
class D extends C{
public void m2() throws IOException{}
//public void m2() throws FileNotFoundException{}
}