2021.10.20
异常:
异常是Java中提供的一种识别及响应错误情况的一致性机制。有效地异常处理能使程序更加健壮、易于调试。
异常发生的原因有很多,比如:
- 用户输入了非法数据
- 要打开的文件不存在
- 网络通信时连接中断
- JVM内存溢出
- 这些异常有的是因为用户错误引起,有的是程序错误引起的,还有其它一些是因为物理错误引起的。
常见异常:
空指针
下标越界
栈内存溢出
类型转换异常
继承体系:
Error:
系统内部错误,这类错误由系统进行处理,程序本身无需捕获处理。
比如:OOM(内存溢出错误)、VirtualMachineError(虚拟机错误)、StackOverflowError(堆栈溢出错误)等,一般发生这种情况,JVM会选择终止程序。
Exception:
Exception是所有异常类的父类。分为非RuntimeException和RuntimeException 。
- 非RuntimeException
指程序编译时需要捕获或处理的异常,如IOException、自定义异常等。属于checked异常。- RuntimeException
指程序编译时不需要捕获或处理的异常,如:NullPointerException等。属于unchecked异常。一般是由程序员粗心导致的。如空指针异常、数组越界、类型转换异常等。常用方法:
public String getMessage() 返回关于发生的异常的详细信息,这个消息在Throwable类的构造函数中初始化了
public void printStackTrace() 打印错误的追踪栈帧
package study.exception;
/**
* 异常发生的原因有很多,尤其是用户输入和要打开的资源不存在
*
* 这些异常出错后,会导致程序生命周期中止执行,从错误代码开始,之后的代码都不会执行
*
* java中有一个专门模拟异常的类,称之为Throwable,所有异常都继承这个类
* @author 落华见樱
*
*/
public class Part01 {
public static void main(String[] args) {
System.out.println(1);
System.out.println(3);
//运行时出错
String s=null;
s.equals("");
System.out.println(4);
System.out.println(6);
}
}
package study.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* 处理异常的两种方式: 1 throws :抛出异常,告诉调用处,这里可能有什么问题
*
* 如果你将异常抛给了调用处,那么调用处要么也抛出去,要么解决
*
* 2 try.....catch....... :解决异常
*
* try{
* 高风险代码;
* }catch(异常类型 变量){
* 解决方案;
* }
*
* @author 落华见樱
*
*/
public class Part02 {
// public static void main(String[] args) throws FileNotFoundException {
public static void main(String[] args) {
// 打开资源文件
try {
FileInputStream fis = new FileInputStream("D:/xxx");
System.out.println(123);
} catch (FileNotFoundException e) {
// 打印错误的追踪栈帧,比较常用,适合程序员排错
// e.printStackTrace();
// 获取错误信息,适合响应给用户
String msg = e.getMessage();
System.out.println(msg);
}
System.out.println(456);
}
}
package study.exception;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Part03 {
}
class A{
public void m1() throws IOException{
}
}
class B extends A{
@Override
// 方法覆写,不能比原方法拥有更宽泛的异常
// 抛出的异常类,可以是父类方法中抛出的类,也可以是对应的子类 , 但是不能是它的父类
// 父类抛出一个异常A , 那么子类 要么还抛出A , 要么抛出A的子类, 要么不抛异常 , 但是不能是A的父类
public void m1() throws FileNotFoundException{
}
}
package study.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* throws 抛出异常,并不会处理异常,是一种提醒机制
*
* 如果你调用 的方法,抛出一个编译时异常,要么你就try..catch处理掉,要么你也抛出
*
* throws 是抛出异常,并不会解决异常,一般用于类库端(被调用的这个类)
*
* 而 try...catch... 是解决异常的,一般用于客户端(调用其他类的这个类,一般客户端都有main方法)
*
* @author 落华见樱
*
*/
public class Part04 {
public static void main(String[] args) throws FileNotFoundException {
m1();
}
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");
}
}
package study.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
/**
* try{
* 高风险代码;
* } catch(异常类型 变量){
* 处理方案;
* } catch(异常类型 变量){
* 处理方案;
* }...
*
* catch中异常类型 不能有继承关系,如果有继承关系,需要从子类到父类
* @author 落华见樱
*
*/
public class Part05 {
public static void main(String[] args) {
try {
FileInputStream fis = new FileInputStream("");
} catch (FileNotFoundException e) {
System.out.println("找不到文件");
} catch (NullPointerException e) {
System.out.println("不能为null");
} catch (Exception e) {
System.out.println("其他异常");
}
}
}
package study.exception;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Part06 {
// 抛异常 可以同时抛出多个,逗号隔开,没有先后顺序
public static void main(String[] args) throws Exception,
FileNotFoundException, IOException {
}
}
package study.exception;
/**
* finally : 必须执行的语句块 比如 打开的资源,需要关闭
*
* 1 finally 不能单独出现,必须和try一起使用 或者和 try...catch...一起使用
*
* 2 finally语句块 只有一种不执行的情况,那就是关闭虚拟机 System.exit(0);
* @author 落华见樱
*
*/
public class Part07 {
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");
}
}
package study.exception;
public class Part08 {
public static void main(String[] args) {
int result = m1();
// 11
System.out.println(result);
}
public static int m1() {
int i = 10;
try {
// 因为finally中有return,并且优先级是比较高的
// 所以在编译的时候 就把这里的return去掉了,只有i++
System.out.println("assass");
return i++;
// i++;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 11
System.out.println(i+"------------");
return i;
}
}
}
package study.exception;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Part09 {
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();
}
}
}
}
package study.exception;
import java.io.FileInputStream;
/**
* Java1.7新特性 自动关闭资源
*
* try{
* 开启资源;
* }catch(异常类型 变量){
* 处理措施;
* }finally{
* 关闭资源
* }
*
* -----
*
* try(开启资源){
* 高风险代码;
* }catch(异常类型 变量){
* 处理措施;
* }
* @author 落华见樱
*
*/
public class Part10 {
public static void main(String[] args) {
// 自动关闭资源
try(FileInputStream fis = new FileInputStream("xxx");){
// 操作
}catch (Exception e) {
e.printStackTrace();
}
}
}
自定义异常类:
怎么自定义
1 继承一个已有的异常类
判断你应该是运行是异常还是编译时异常,如果是运行时异常需要继承 RuntimeException 否则就继承Exception即可,一般情况下 我们写的 一定是 编译时异常
2 公共的无参构造3 公共的有参构造
,传入字符串,并在构造方法中把该字符串传递给父类
package study.throw_;
/**
* 1 继承一个已有的异常类
* 判断你应该是运行是异常还是编译时异常,如果是运行时异常需要继承 RuntimeException 否则就继承Exception即可
* 一般情况下 我们写的 一定是 编译时异常
* 2 公共的无参构造
* 3 公共的有参构造,传入字符串,并在构造方法中把该字符串传递给父类
* @author 落华见樱
*
*/
public class UserException extends Exception{
public UserException() {
}
public UserException(String msg) {
super(msg);
}
}
package study.throw_;
public class UserService {
public static void login(String username,String password) throws UserException{
if (username.equals("admin")) {
if (password.equals("root")) {
// TODO 登陆成功
// return "登陆成功";
}else {
// TODO 密码不正确
// return "密码不正确" ;
throw new UserException("密码不正确");
}
}else{
// TODO 用户名不正确
// return "用户名不正确";
throw new UserException("用户名不正确");
}
}
}
package study.throw_;
import java.util.Scanner;
/**
* 需求 完成用户登陆
*
* 1 如果用户名不是admin 则提示用户名不存在 2 如果密码不是root 则提示密码不正确
*
* 客户端负责数据录入
*
* service 负责 逻辑校验
* @author 落华见樱
*
*/
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();
// System.out.println(username+" : "+password);
// String result = UserService.login(username, password);
// if (result.equals("登陆成功")) {
// System.out.println("欢迎回来");
// }else{
// System.out.println(result);
// }
try {
UserService.login(username, password);
System.out.println("登陆成功");
} catch (UserException e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}