1.异常机制
1.1 异常是什么
异常是java中提供的一种识别及响应错误情况的一致性机制,有效地异常处理能使程序更加简装,鲁棒性更好 鲁棒性:在程序遇到危险情况的时候,不死机不关机
异常发生的原因有很多,比如:
1) 用户输入了非法数据
2} 要打开的文件不存在
3} 网络通信时连接中断
4} JVM内存溢出
5} 这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其他一些是因为物理错误引起的
异常发生后,会导致程序的生命周期停止,从错误代码开始,以后的代码都不会执行
java中,有一个专门模拟异常的类Throwable,所有的异常都继承这个类
1.2 之前常见的异常
空指针 下标越界 栈内存溢出 类型转换异常
1.3 继承体系
1.4 Error
1.系统内部出现的错误,这类错误不用我们管,由系统自行处理,程序不需要捕获这类错误
比如:OOM(内存溢出错误)等
一般发生这种情况,JVM会选择终止程序
2.Exception
2.1 是什么
Exception是所有异常类的父类,分为运行时异常(RuntimeException)和非运行时异常
-非运行时异常
指程序编译时需要捕获或者处理的异常,IOException,自定义异常等
-运行时异常
指程序编译时不需要捕获或者处理的异常,如:空指针异常,一般是由程序员粗心导致的,如空指针异常,数组越界,类型转换异常
2.2 常用的方法
getMessage用于向用户打印错误信息
printStackTrace用于程序员排错
2.3 异常处理的两种方式
1.throws 抛出异常给调用处,告诉调用处,我这里可能会出什么问题
如果你把异常给了调用处,那么调用处要么也抛出去,要么就地解决
2.try{}catch(){} 解决异常
public static void main(String[] args) throws FileNotFoundException {
//打开资源文件
try{
FileInputStream fis = new FileInputStream("D:/xxxx");
System.out.println(123) ;
}catch(FileNotFoundException e){
// 打印错误的追踪栈帧,比较常用,适合程序员排错
// e.printStackTrace();
// 获取错误信息,适合响应给用户
String msg = e.getMessage();
System.out.println(msg);
}
2.4 try...catch....
第一种用法:
try{高风险代码;}
catch(异常类型 变量){解决方案 ;}
第二种用法:
try{高风险代码;}
catch(异常类型 变量){处理方案;}
catch(异常类型 变量){处理方案;}
catch(异常类型 变量){处理方案;}
try{
FileInputStream fis = new FileInputStream("") ;
}catch(FileNotFoundException e){
System.out.println("找不到文件");
}catch(NullPointerException e){
System.out.println("不能为空");
}catch(Exception e){
System.out.println("其他异常");
}
第三种用法:
try(开启资源){高风险代码 ;}
catch(异常类型 变量){处理措施 ;}
//自动关闭资源
try(FileInputStream fis = new FileInputStream("xxx");){
//操作
}catch(Exception e){
e.printStackTrace();
}
覆写方法时,子类不能拥有比父类更宽泛的异常
2.5 throws
1.是什么
throws会抛出异常但不会解决异常,是一种提醒机制
2.使用方式
如果你调用了一个方法,这个方法编译时抛出了一个异常,那么你接受到了异常之后要不就解决try...catch...要不就抛出throws给你的调用处
public static void main(String[] args) {
try {
m1() ;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void m1() throws FileNotFoundException{
m2() ;
}
public static void m2() throws FileNotFoundException{
m3() ;
}
public static void m3() throws FileNotFoundException {
FileInputStream fis = new FileInputStream("xxx");
}
可以同时抛出多个异常
//抛异常可以同时抛出多个异常,以逗号隔开,没有先后顺序
public static void main(String[] args) throws FileNotFoundException,IOException {
}
3.Finally
3.1 finally是什么
finally是必须执行的语句块
使用场景:打开的资源,需要关闭,那么关闭的代码就可以写在finally里面
3.2 如何使用
1,finally不能单独出现,必须和try一起使用或者和try...catch一起使用
2.finally语句块只有一种不执行的情况,那就是关闭虚拟机System.exit(0) ;
public static void main(String[] args) {
try {
int a = 0;
int b = 3;
// 除数不能为0,会出错
int c = b / a;
System.out.println(c);
} catch (Exception e) {
e.printStackTrace();
// 终止方法执行
return;
// System.exit(0);
} finally {
// 但是finally会执行
System.out.println("2222");
}
// 执行不到,因为上面有return
System.out.println("1111");
}
到了return后,本来程序应该终止的,但是看到了finally所以先把finally语句块的内容执行完了再return终止程序
3.3 注意事项
3.4 应用场景
关闭打开的资源
public static void main(String[] args) {
FileInputStream fis = null;
try {
// 打开资源
fis = new FileInputStream("xxx");
// xx 操作
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
// 判断是否打开资源,如果打开 就关闭
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.Throw
4.1 throw是什么
throw是异常源点
throw new 异常类(错误信息) ;
怎么用:参考自定义异常
5.自定义异常类
5.1 怎么用
1.继承一个已有的异常类
判断你自定义的这个异常类是运行时异常还是非运行时异常,运行时异常继承RuntimeException,否则就继承Exception即可
一般情况下,我们写的是,编译时异常就是Exception
2.公共的无参构造
3.公共的有参构造,形参为字符串,并在方法体中利用super(msg);传给父类
实例:
public class UserException extends Exception{
public UserException(){
}
public UserException(String message){
super(message) ;
}
}
5.2 应用场景
public class Client {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in) ;
System.out.println("请输入用户名和密码 : ") ;
String username = scanner.next() ;
String password = scanner.next() ;
try{
UserService.login(username, password);
System.out.println("登录成功") ;
}catch(UserException e){
System.out.println(e.getMessage()) ;
}
}
}
public class UserService {
public static void login(String username ,String password) throws UserException{
if(username.equals("admin")){
if(password.equals("root")){
}else{
throw new UserException("密码不正确") ;
}
}else{
throw new UserException("用户名不正确") ;
}
}