异常介绍。

异常

1. 了解异常的概念

编写的程序是来源或超脱于现实生活的。

生活中 不符合你预期情况的场景 就是出现异常了!

程序中的异常:

Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
int num1 = in.nextInt();
System.out.print("请输入除数:");
int num2 = in.nextInt();
System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
System.out.println("感谢使用本程序!");

生活中不能放弃,程序中也不能放弃。

程序中的解决方案为:(代码臃肿,补足很困难!)

Scanner in = new Scanner(System.in);
System.out.print("请输入被除数:");
// hasNextXXX()  判断Scanner接收到的你输入的值 是否是某个类型  如果是为true
if(in.hasNextInt()) {
	// 将类型进行转换 
	int num1 = in.nextInt(); 
	System.out.print("请输入除数:");
	if(in.hasNextInt()) {
		int num2 = in.nextInt();
		// 排除掉0为除数场景
		if(num2 == 0) {
			System.out.println("除数不能为0!");
		}else {
			System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
		}
	}else {
		System.out.println("对不起!除数必须为整数!");
	}
}else {
	System.out.println("对不起!被除数必须为整数!");
}
System.out.println("感谢使用本程序!");

异常:程序中出现了不正常情况,会导致程序中断!

2.理解Java异常处理机制

**try:**尝试 试图

**catch:**捕捉 抓住

**finally:**最终的 最后的

**throw:**抛出 扔

**throws:**抛出 扔 (Java编程网络释义:声明异常)

2.1 会捕捉异常(try-catch)

  1. try-catch

    // 可能有代码段
    try{
        // 可能会出现异常问题的代码
    }catch(异常类型  形参名){
        // 出现了异常  解决异常的代码
    }
    // 可能有代码段1
    

    **正常情况:**与没加效果一致

    **出现了异常(声明了可以捕获):**当try块中的某一行代码出现了异常,那么try块中的后续代码将不再执行,直接会跳转到catch块中进行异常的处理,处理完之后继续向下执行。 // 可能有代码段1这部分继续往下走

    **出现了异常(异常类型不匹配):**当try块中的某一行代码出现了异常,那么try中的后续代码将不再执行,catch块中声明的异常类型不匹配,那么异常将不会被处理,会采用默认处理方式。(它就好像你没加过try-catch一样) // 可能有代码段1这部分也就不往下走

    **联想:**缉毒警察解决不了防暴警察的活。

  2. try-catch-catch…

    多重catch的情况(联想多重if)

    **特点:**当出现异常时,会自上而下的进行判断,判断是否符合catch块中的异常,如果能符合,直接执行此catch块,后续的catch不会触发!

    ​ 联想多重if记住 最容易匹配的 不要放在前方。 因为多态的原因,如果你将父类放在上方,下方的子类catch就不会执行了!

    Scanner in = new Scanner(System.in);
    try {
    	// 可能会出现问题的代码
    	System.out.print("请输入被除数:");
    	int num1 = in.nextInt();
    	System.out.print("请输入除数:");
    	int num2 = in.nextInt();
    	System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
    }catch(InputMismatchException e) {
    	// 出现了问题之后 如何解决
    	System.out.println("输入不匹配!必须输入整数!");
    	e.printStackTrace();
    }catch(ArithmeticException e) {
    	System.out.println("除数不能为0!");
    	System.err.println(e.getMessage());
    }catch(Exception e) {
    	System.out.println("有异常出现:"+e.getMessage());
    }
    System.out.println("感谢使用本程序!");
    
  3. try-catch-finally

    **特点:**无论try块中代码是否有异常,都会执行finally块中的代码片段。

    1.出现了退出虚拟机语句 : System.exit(0);

    2.return关键字:结束当前方法,返回到方法的调用者处。 当try-catch中同时出现了return和finally块,它会先执行finally块中的代码,然后才执行return。

    Scanner in = new Scanner(System.in);
    try {
    	System.out.print("请输入被除数:");
    	int num1 = in.nextInt();
    	System.out.print("请输入除数:");
    	int num2 = in.nextInt();
    	System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
    }catch(InputMismatchException e) {
    	System.out.println("输入不匹配!");
    	return;
    }finally { // 无论是否出现异常  都会执行!
    	System.out.println("感谢使用本程序!");
    }
    

注意事项:

​ try、catch 、finally可以随意组合,但是它们不能单独出现。

异常出现之后,究竟JVM在做什么事?

​ 当异常出现之后,JVM中会帮你创建对应异常类型的对象(例如:new InputMismatchException(异常提示信息)),如果没有(能处理的)try-catch,采用默认将异常信息进行封装 然后在控制台打印。

异常的堆栈跟踪信息:(我们也可以通过异常对象的方法 printStackTrace()来输出异常的堆栈跟踪信息)

Exception in thread "main"(异常出现在哪个线程) java.lang.ArithmeticException(出现了什么类型的异常): / by zero(异常的缘由信息)
	at cn.kgc.demo2.Demo1.main(Demo1.java:21) (异常出现的位置  具体到某个包下的某个类下的某个方法 类中的第几行)
Exception in thread "main" java.util.InputMismatchException
	at java.util.Scanner.throwFor(Scanner.java:864) // 异常出现的根本位置
	at java.util.Scanner.next(Scanner.java:1485)
	at java.util.Scanner.nextInt(Scanner.java:2117)
	at java.util.Scanner.nextInt(Scanner.java:2076)
	at cn.kgc.demo2.Demo2.main(Demo2.java:10) // 异常出现的直接位置

如果有能够处理的try-catch块,那么JVM会将这个异常对象传给catch(异常类型 形参名)块,然后你就可以通过形参去查看异常相关信息或做对应异常处理了。

2.2 会抛出异常(throws throw)(JavaWeb部分会再次提到用法)

不处理 ->

之所以出现throw和throws的目的就是当某个位置出现异常之后,如果它不想处理就可以将此异常上抛,上抛给调用者。

后期的常用形式:为了借助finally块的特点,处理完最终执行内容之后,再将异常上抛。

throws:后面的接的是此方法可能出现的异常的类型 可以同时指定多个 逗号隔开

throw:用来抛出异常对象。

子类重写父类方法:

​ 子类重写父类方法,这个方法不能抛出比父类更多的异常,也不能抛出更大的异常。

3. 了解Java异常体系结构(类的家族树)

在这里插入图片描述

在这里插入图片描述
**Error:**程序无法通过代码来修复!必须人工干预解决。 OutOfMemoryError 内存溢出 StackOverflowError 堆栈溢出等 编译错误(语法错误)等

**Exception:**程序执行过程中,可能会出现一些问题,可以提前做好处理工作。

​ **RuntimException:**运行时异常 例如:InputMismatchException ArrayIndexOutOfBoundsEception NullPointerException ClassCastException 运行期间 可能会出现这些错误!

​ **checked异常:**受检异常/检查异常 Java程序中人家认为这种异常很可能出现,所以必须要提前解决!增强程序的健壮性!

自定义异常:

/**
 * 自定义异常(异常种类更加丰富   更加具体)
 * @author Charles7c
 * 2019年2月18日 上午11:51:42
 */
public class IllegalAgeException extends RuntimeException{
	
	public IllegalAgeException(String message) {
		super(message);
	}

	public IllegalAgeException() {
		
	}
}
public class Student implements Serializable{

	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	
	// throws是声明异常 声明可能出现的异常 后面追的是异常类型
	// throw是抛出异常 后面追的是异常对象
	public void setAge(int age) throws Exception {
		// 加入逻辑控制语句
		if(age < 0 || age > 120) {
			// System.out.println("年龄有问题!老妖怪还是小妖精!");
			// throw new Exception("年龄有问题!老妖怪还是小妖精!");
			throw new IllegalAgeException("年龄有问题!老妖怪还是小妖精!");
		}else {
			this.age = age;
		}
	}
	
	public Student() {
		super();
	}
	
}
public class Test {

	// 创建日志对象
	public static Logger logger = Logger.getLogger(Test.class);
	
	public static void main(String[] args) {

		Student student = new Student();
		logger.info("创建好了学生对象!");
		student.setName("小花");
		logger.info("正在给姓名进行赋值:赋值内容为:"+student.getName());
		try {
			student.setAge(290);
		} catch (Exception e) {
			//打印异常堆栈信息
			// e.printStackTrace();
			//输出异常提示信息  年龄有问题!老妖怪还是小妖精!
			System.err.println("出现了异常!"+e.getMessage());
			logger.error(e.getMessage());
		}
		/*try {
			FileInputStream fileInputStream = new FileInputStream("d:/a.txt");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}*/
	}

}

mybatis中方法名不一致时报错
在这里插入图片描述

在这里插入图片描述

4、try-witch-resource

  //使用 try-with-resource 语句
    public static void doNotCloseResourceInTry_good() throws IOException {
        //用 try-with-resource 语句不用写finally块 因为会在FileInputStream类中进行关闭处理
        //如果你的资源实现了 AutoCloseable 接口,你可以使用这个语法。
        //大多数的 Java 标准资源都继承了这个接口。当你在 try 子句中打开资源,资源会在 try 代码块执行后或异常处理后自动关闭。
        File file = new File("./znote.txt");
        try ( FileInputStream inputStream = new FileInputStream(file);){
            int read = inputStream.read();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

继承是实线 接口是虚线
在这里插入图片描述

try-with-resource:Java 7中引入的

5. (目前作为了解) 异常记录 - 日志(log4j)

日志:(记录东西) 在程序运行期间 记录程序的状态 、用户操作行为、异常情况的一种东西。

*.log

日志是为了以后我们分析程序运行情况和解决问题的根据!重要!

日志记录工具/框架:log4j(log for java) logback

  1. 下载jar包(人家编写的代码的字节码压缩包)
  2. 将Jar包引入到你的工程内(先建立一个lib文件夹,将jar包放进去,右键jar包进行build path)
  3. 像使用JRE内的类库一样去使用它即可。

info(); 记录普通信息的

error(); 记录错误信息的

debug(); 可以用来记录一下特别的普通信息的

至于log4j配置文件的编写工作,可以自行查看提供的注释和文档。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值