Java基础 自学讲义 4. 异常 断言和日志

目录
一.处理错误
二.捕获异常

  1.try-catch语法
  2.finally子句
  3.堆栈轨迹 Trace Stack

三.使用异常机制的技巧
四.断言
五.日志

一.处理错误

在我们写程序的时候可能会遇到各种各样的错误:
有的是因为代码写错了, 比如逻辑错了, 语法错了, 数组越界了, 死循环了(这些不能异常处理, 只能自己好好debug改一改哈哈)等等原因;
也可能是因为其他原因比如我希望在某个地方打开一个文档, 但是该路径下并没有这个文件, 或者没有权限打开这个文件;
也有可能是我想调用网络, 但是没有网络访问权限;
Java可以使用throws来抛出异常, 所有的异常类都派生自Throwable类, 其有两个子类是Error和Exception;
异常分类
Error 类层次结构描述了 Java 运行时系统的内部错误和资源耗尽错误。这个比较无奈, 一般情况下不能这样瞎搞, 如果实在没办法, 那抛出异常也并没有卵用了, 只能及时终止程序, 所以这种情况要尽量避免;
在设计 Java 程序时, 需要关注 Exception 层次结构。 这个层次结构又分解为两个分支: 一个分支派生于RuntimeException; 另一个分支包含其他异常。划分两个分支的规则是:由 程序错误导致的异常属于RuntimeException; 而程序本身没有问题,但由于像I/O错误这类 问题导致的异常属于其他异常, 比如IOException;

如果希望在某个方法提示可能出现的异常, 可以在方法的大括号前面加上throws + 预期可能会出现的异常, 比如 throws IOException, 当然也可以这样表示接受所有异常:

public static void main(String[] args) throws Exception{
	//***code***
}

Java提供了一些标准的异常, 比如下面这些, 随便列了一些不全 ?
标准异常
但是错误的种类千奇百怪 ? ?
所以java支持自定义派生于Exception类的子类----自己的异常类:
比如下面我自己定义的FileFormatException异常:

import java.io.*;

class test11 {
	public static void main(String[] args) throws FileFormatException {
		boolean isExceptionOccur = true;
		if(isExceptionOccur) throw new FileFormatException();
	}
}

class FileFormatException extends IOException{
	public FileFormatException(){}
	public FileFormatException(String gripe){
		super(gripe);
	}
}

要注意, 如果想在程序中使用throws xxException这样的语句, 一定要在当前的方法后面加上throws xxException

二.捕获异常

1.try-catch语法

可以使用try-catch语法来捕获异常, 异常发生后将不会执行异常部位后面的代码, 直接进入catch代码块, 可以使用多个的catch语法;

		try {
			/*code*/
		} 
		catch (Exception e1) {
			/*code*/
		}
		catch (Exception e2) {
			/*code*/
		}
		catch (Exception e3) {
			/*code*/
		}

还可以使用再次抛出异常和异常链:

try {
			System.out.println(a[10]);
		} catch (Exception e) {
			throw new FileFormatException();
		}

1
2

2.finally子句

可以使用finally子句用于关闭某些输入流或者资源, 使用close()方法,
finally
这里有一点需要注意的地方是, finally语句是无论如何都会进入执行的, 如果程序没有任何异常, 那么会在执行完try内的语句后执行finally, 如果程序出现了异常, 那么会在执行完catch语句的内容后执行finally, 就算程序在try的语句中已经return了也会继续执行finally中的语句, 会覆盖return的内容, 比如在下面的例子中:

class test11 {
	public static void main(String[] args) throws Exception {
		System.out.println(f(3));//输出结果为0 而不是9
	}
	public static int f(int x){
		try {
			return x*x;
		} catch (Exception e) {
			
		}
		finally {
			return 0;
		}
	}
}

当然如果使用了System.exit(0);那就会直接退出不执行finally中的语句了;

3.堆栈轨迹 Trace Stack

使用getStackTrace方法, 它会得到StackTraceElement对象的一个数组, 可以在你的程序中分析这个对象数组:
TraceStack

三.使用异常机制的技巧

1.异常处理不能代替简单的测试

执行简单测试花费的时间比捕获异常少很多

使用异常的基本原则:只在异常情况下使用异常机制

2.不要过分的细化异常

每条语句都封装在独立的try语句块中,将导致代码量的急剧膨胀

3.利用异常层次结构

1.不要只抛出IOException,应该寻找更加适合的自子类或者创建自己的异常类
2.不要只捕获Throwable,否则,会使程序代码更难读、更难维护
3.考虑已检查异常和未检查异常的区别
4.将一种异常转换为另一种更合适的异常时不要犹豫

4.不要压制异常

编译器会对所有调用这个方法的方法进行异常处理的考虑,如果认为异常非常重要,就应该对它们进行处理

	try{
    	code that threatens to throw checked exceptions 
	}
	catch(Exception e){
	
	}

这段代码可以通过编译,除非发生异常,否则它将可以正常运行,即使发生了异常也会被忽略

5.在检测错误时,“苛刻”要比放任更好

例如,当栈为空时,在出错的地方抛出一个EmptyStackException比在后面抛出一个NullPointerException更好

6.不要羞于传递异常

传递异常比捕获异常更好,让高层次的方法通知用户发生了错误,或者放弃不成功的命令更合适

规则5、6归纳为“早抛出,晚捕获”

四.断言

cuowu
Java中的断言用assert关键词, 使用这样的语法:

assert statement1:statement2;

语法形式有两种形式:
1、assert condition; 这里condition是一个必须为真(true)的表达式。如果表达式的结果为true,那么断言为真,并且无任何行动如果表达式为false,则断言失败,则会抛出一个AssertionError对象。这个AssertionError继承于Error对象,而Error继承于Throwable,Error是和Exception并列的一个错误对象,通常用于表达系统级运行错误。
2、asser condition:expr; 这里condition是和上面一样的,这个冒号后跟的是一个表达式,通常用于断言失败后的提示信息,说白了,它是一个传到AssertionError构造函数的值,如果断言失败,该值被转化为它对应的字符串,并显示出来。

使用断言在编译的时候要使用-ea来运行程序

javac test.java
java -ea test

五.日志

1.基本日志

要生成简单的日志记录,可以使用全局日志记录器(global logger)并调用其 info 方法;
也可以使用setlevel(Level.OFF)来取消记录日志;(在main程序的开头调用)
如下:

import java.util.logging.*;

class test11 {
	public static void main(String[] args) {
		int a = faq(1);
		Logger.getGlobal().info("Cpt");
		Logger.getGlobal().setLevel(Level.OFF);
		Logger.getGlobal().info("GodV");
	}
	public static int faq(int n ){
		Logger.getGlobal().info("aluka");
		return n*n;
	}
}
//output: 
//Oct 06, 2018 2:41:20 AM test11 faq
//INFO: aluka
//Oct 06, 2018 2:41:20 AM test11 main
//INFO: Cpt
2.高级日志

我们可以创建自己的记录器logger:

private static final Logger myLogger = Logger.getLogger("com.mucompany.myapp");

记录级别有以下几种: 常用的有前面3种, 还有OFF和ALL;
使用setLevel设置等级;

日志级别 描述
OFF 关闭:最高级别,不输出日志。
FATAL 致命:输出非常严重的可能会导致应用程序终止的错误。
ERROR 错误:输出错误,但应用还能继续运行。
WARN 警告:输出可能潜在的危险状况。
INFO 信息:输出应用运行过程的详细信息。
DEBUG 调试:输出更细致的对调试应用有用的信息。
TRACE 跟踪:输出更细致的程序运行轨迹。
ALL 所有:输出所有级别信息。

后面还有一些内容我自己也没太明白, 附上两篇博客吧:
Java 程序如何正确地打日志
Java日志终极指南
感觉这个日志还是在实际项目中比较有用, 我还不太能理解好;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值