import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.nio.channels.OverlappingFileLockException;
import java.security.spec.ECField;
import java.util.logging.Logger;
public class Ans {
public static void main(String[] args) {
//test2();
test4();
test5();
test6();
}
static void test0() {
//异常分为两类,error和exception,error是程序严重错误,无法恢复,包括:OutOfMemoryError 内存耗尽,NoClassDefFoundError 无法加载某个Class,StackOverflowError 栈溢出。Exception是运行时错误,可以捕捉并恢复,分为RuntimeException(可以不被捕捉),和非RuntimeException(必须被捕捉)
//如果不想捕捉异常,可以在main函数中throws
}
static void test1() {
//由于异常捕获从上向下,且捕获一个后与其并列的不会再捕获,所以子类异常应当写在前面
//finally中的语句无论如何都会最后执行,且一定执行(没有异常也执行)
}
static void test2() {
class A {
void a(String s) {
if (s==null)
throw new NullPointerException();
}
void b() {
try {
a(null);
} catch (Exception e) {
throw new IllegalArgumentException(); //如果这样做就会丢失NullPointerException的信息
}
}
void b2() {
try {
a(null);
} catch (Exception e) {
throw new IllegalArgumentException(e); //这样便可以保存以前的信息
}
}
void c() {
try {
a(null);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
finally {
throw new UnsupportedOperationException(); //这里抛出一个异常会直接掩盖前面的异常,因为finally最后执行,且一段代码只能抛出一个异常
} //但这种情况其实很少见
}
void c2() throws Exception {
Exception origin = null;
try {
a(null);
} catch (Exception e) {
origin = e;
throw new IllegalArgumentException(e);
}
finally {
Exception e = new UnsupportedOperationException();
if (origin!=null)
e.addSuppressed(origin); //这种方式可以解决异常掩盖问题
throw e;
}
}
}
A a = new A();
try {
a.a(null);
} catch (Exception ne) {
ne.printStackTrace(); //这样打印异常
}
try {
a.b();
} catch (Exception e) {
e.printStackTrace();
}
try {
a.b2();
} catch (Exception e) {
e.printStackTrace();
}
try {
a.c();
} catch (Exception e) {
e.printStackTrace();
}
try {
a.c2();
} catch (Exception e) {
e.printStackTrace();
}
}
static void test4() {
//在编写程序时我们可以使用断言
//这样其实不会抛出错误,因为JVM默认关闭断言,需要在IDEA中设置,或者使用命令行
int i = -1;
assert i>0; //在这里断言失败,会抛出AssertionError,由于时Error因此无法恢复,断言常常用于开发和调试,而正式产品中应当使用异常
System.out.println(i);
assert i>0:"i must be larger than 0"; //断言中可以包含信息
}
static void test5() {
//在编写程序时的一个好习惯是生成日志,日志的好处在于减少用于就错的代码,而且有详细的信息
//https://www.liaoxuefeng.com/wiki/1252599548343744/1264738568571776 可以查看博客信息,当然博客中讲的也比较浅
//同时这种标准库自带的JDK Logging不是非常好用,以后可以试试更先进的
Logger logger = Logger.getGlobal();
logger.info("start process");
logger.severe("no no no");
}
static void test6() {
//Commons Logging是一个第三方日志库,需要载入工程中,它可以挂载不同的日志系统,默认下使用Log4j,如果没有就是用JDK Logging
class A {
void a() {throw new RuntimeException(); }
}
Log log = LogFactory.getLog(Ans.class);
log.info("begin");
log.warn("end");
try {
A a = new A();
a.a();
} catch (Exception e) {
log.error("catch it!!",e); //这种方法可以反映捕获异常
}
}
static void test7() {
//Log4j的功能非常强大,由于其配置不方便,开发阶段如果不需要引入Log4j可以暂时使用Commons Logging,此是Commons Logging默认使用JDK Logging
//等到需要使用Log4j时可以配置并使用,这时Commons Logging将自动切换至Log4j,不需要改动任何代码
}
static void test8() {
//相对于Log4j 与Commons Logging,还拥有另一对日志工具SLF4J与Logback
}
}