java笔记5-java异常处理

Java的异常

异常
Java使用异常Exception来表示错误

  • Exception是Class,带有类型信息
  • 可以在任何地方抛出
  • 只需要在上层捕获,和方法调用分离

必须捕获的异常称为Checked Exception
不需要捕获的异常包括RuntimeException和Error
捕获异常使用try...catch
不捕获的Checked Exception必须用throws声明
main()是最后捕获异常的机会

捕获异常
捕获异常使用try...catch
catch会捕获对应的Exception及其子类
多个catch子句从上到下匹配
顺序非常重要,子类必须在前
finally保证有无错误都会执行
finally可选
使用multi-catch捕获多种类型异常

抛出异常
异常从下往上抛出,直至被捕获
打印方法调用栈:printStackTrace()
用throw语句抛出异常
转换异常时注意保留原始异常信息
抛出异常前会保证执行finally
finally如果抛出异常会导致suppressed exception
获取所有异常信息:getSuppressed()

自定义异常
尽量使用JDK已定义异常
自定义异常从RuntimeException派生
先定义BaseException,再派生子类
自定义异常应该提供多个构造方法
可以使用IDE根据父类快速创建构造方法

 

断言 Assertion


断言使用assert语句
JVM默认关闭断言指令:

  • 给Java虚拟机传递-ea参数启用断言
  • 可以指定特定的类启用断言 -ea:com.feiyangedu.sample.Main
  • 可以指定特定的包启用断言 -ea:com.feiyangedu...

特点:

  • 断言是一种调试方式,断言失败会抛出AssertionError,导致程序退出
  • 只能在开发和测试阶段启用断言
  • 对可恢复的错误不能使用断言,而应该抛出异常
  • 断言很少被使用,更好的方法是编写单元测试

 

使用JDK Logging


日志 Logging

  • 日志是为了替代System.out.println(),可以定义格式,重定向到文件等
  • 日志可以存档,便于追踪问题
  • 日志记录可以按级别分类,便于打开或关闭某些级别
  • 可以根据配置文件调整日志,无需修改代码

JDK提供了Logging:java.util.logging
JDK Logging定义了7个日志级别:

  • SEVERE
  • WARNING
  • INFO (默认级别)
  • CONFIG
  • FINE
  • FINER
  • FINEST

JDK Logging的局限:

  • JVM启动时读取配置文件并完成初始化
  • JVM启动后无法修改配置
  • 需要在JVM启动时传递参数 -Djava.util.logging.config.file=config-file-name
package com.feiyangedu.sample;

import java.util.logging.Level;
import java.util.logging.Logger;

public class Main {

	public static void main(String[] args) {
		Logger logger = Logger.getGlobal();
		logger.setLevel(Level.WARNING);
		logger.info("Create new person...");
		Person p = new Person("Xiao Ming");
		System.out.println(p.hello());
		try {
			new Person(null);
		} catch (Exception e) {
			logger.log(Level.WARNING, "Create new person failed", e);
		}
		logger.info("Program end.");
	}

}
package com.feiyangedu.sample;

public class Person {

	private final String name;

	public Person(String name) {
		if (name == null) {
			throw new IllegalArgumentException("name is null.");
		}
		this.name = name;
	}

	public String hello() {
		return "Hello, " + name + "!";
	}
}

输出:

Hello, Xiao Ming!
十二月 16, 2018 3:43:17 下午 com.feiyangedu.sample.Main main
警告: Create new person failed
java.lang.IllegalArgumentException: name is null.
	at com.feiyangedu.sample.Person.<init>(Person.java:9)
	at com.feiyangedu.sample.Main.main(Main.java:15)

使用Commons Logging

Commons Logging
Commons Logging是Apache创建的日志系统:

  • Commons Logging是使用最广泛的日志模块
  • Commons Logging的API非常简单
  • Commons Logging可以自动使用其他日志模块

Commons Logging定义了6个日志级别:

  • FATAL
  • ERROR
  • WARNING
  • INFO (默认级别)
  • DEBUG
  • TRACE

在Eclipse中引入jar包:
Project -> Property -> Java Build Path -> Libraries -> Add Jars...
初始化Log对象:
final Log log = LogFactory.getLog(getClass());

文档:http://commons.apache.org/proper/commons-logging/

package com.feiyangedu.sample;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Main {
	static Log log = LogFactory.getLog(Main.class);

	public static void main(String[] args) {
		Person p = new Person("Xiao Ming");
		log.info(p.hello());
		try {
			new Person(null);
		} catch (Exception e) {
			log.error("Exception", e);
		}
	}

}
package com.feiyangedu.sample;

public class Person {

	private final String name;

	public Person(String name) {
		if (name == null) {
			throw new IllegalArgumentException("name is null.");
		}
		this.name = name;
	}

	public String hello() {
		return "Hello, " + name + "!";
	}
}

输出:

十二月 16, 2018 3:39:46 下午 com.feiyangedu.sample.Main main
信息: Hello, Xiao Ming!
十二月 16, 2018 3:39:46 下午 com.feiyangedu.sample.Main main
严重: Exception
java.lang.IllegalArgumentException: name is null.
	at com.feiyangedu.sample.Person.<init>(Person.java:9)
	at com.feiyangedu.sample.Main.main(Main.java:13)

 

使用Log4j


Log4j


Log4j的概念:

  • Appender
  • Filter
  • Layout

使用Log4j:

  • 通过Commons Logging实现日志,不需要修改代码即可使用Log4j
  • 使用Log4j只需要把log4j2.xml相关jar放入classpath
  • 如果要更换Log4j,只需要移除log4j2.xml和相关jar
  • 只有扩展Log4j时,才需要引用Log4j的接口

文档:http://logging.apache.org/log4j/

package com.feiyangedu.main;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.feiyangedu.sample.Person;

public class Main {

	static final Log log = LogFactory.getLog(Main.class);

	public static void main(String[] args) {
		log.debug("Program start...");
		String name = "Xiao Ming";
		log.info("Create person " + name);
		Person p = new Person(name);
		log.info("call hello(): " + p.hello());
		try {
			new Person(null);
		} catch (Exception e) {
			log.error("Error when create person.", e);
		}
		log.info("Program end.");
	}

}
package com.feiyangedu.sample;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class Person {

	final Log log = LogFactory.getLog(getClass());

	private final String name;

	public Person(String name) {
		if (name == null) {
			throw new IllegalArgumentException("name is null.");
		}
		this.name = name;
	}

	public String hello() {
		log.debug("Say hello to: " + name);
		return "Hello, " + name + "!";
	}
}

log4j2.xml放在src下

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
	<Properties>
		<!-- 如何打印日志的格式 -->
		<Property name="log.pattern">%d{MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36}%n%msg%n%n</Property>
		<Property name="file.all.filename">log/all.log</Property>
		<Property name="file.all.pattern">log/all.%i.log.gz</Property>
		<Property name="file.err.filename">log/err.log</Property>
		<Property name="file.err.pattern">log/err.%i.log.gz</Property>
	</Properties>
	<Appenders>
		<Console name="console" target="SYSTEM_OUT">
			<PatternLayout pattern="${log.pattern}" />
		</Console>
		<RollingFile name="all" bufferedIO="true" fileName="${file.all.filename}"
			filePattern="${file.all.pattern}">
			<PatternLayout pattern="${log.pattern}" />
			<Policies>
				<!-- 每当log文件达到1M时就自动切割 -->
				<SizeBasedTriggeringPolicy size="1 MB" />
			</Policies>
			<DefaultRolloverStrategy max="10" />
		</RollingFile>
		<RollingFile name="err" bufferedIO="true"
			fileName="${file.err.filename}" filePattern="${file.err.pattern}">
			<PatternLayout pattern="${log.pattern}" />
			<Policies>
				<SizeBasedTriggeringPolicy size="1 MB" />
			</Policies>
			<DefaultRolloverStrategy max="10" />
		</RollingFile>
	</Appenders>
	<Loggers>
		<Root level="info">
			<AppenderRef ref="console" level="info" />
			<AppenderRef ref="all" level="info" />
			<AppenderRef ref="err" level="error" />
		</Root>
		<Logger name="com.feiyangedu.sample" level="debug">
			<AppenderRef ref="console" level="debug" />
		</Logger>
	</Loggers>
</Configuration>

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值