Exception:
异常可分为运行时异常(RuntimeException)和检查时异常(CheckedException)两种:
一、CheckedException:检查时异常
ClassNotFoundException:找不到指定的class类。
Class.forName("java.lang.xxx");
二、RuntimeException:运行时异常
**ArithmeticException:**数学异常
System.out.println(1 / 0);
NullPointerException:空指针异常。
String name = null;
System.out.println(name.trim());
try {
Date date = new Date();
date = null;
System.out.println(date.getYear());
} catch (Exception e) {
e.printStackTrace();
}
ArrayIndexOutOfBoundsException:数组下标越界。
String [] names = new String[2];
System.out.println(names[2]);
NumberFormatException:数字格式转化异常。
String y="1a#0";
int result=Integer.parseInt(y);
System.out.println(result);
三、Java中对异常的处理有如下两种方式:
1>通过try、catch和finally关键字捕获异常;
try {
Date date = new Date();
date = null;
System.out.println(date.getYear());
} catch (Exception e) {
e.printStackTrace();
}finally{
System.out.println("最终都会执行。");
}
try…catch…finally异常处理结构中,try语句块是必须的, catch和finally语句块至少出现一个。
注意:如果try语句块包含的是检查时异常,则在没有通过throws抛出该异常类的情况下,try必须和catch一起使用,当该行代码去掉或注销掉时,catch相应的异常语句块必须去掉
2>通过throw或throws关键字抛出异常;
❶throw用于抛出具体异常类的对象,一般用于方法体中。
public void setAge(int age){
if(age>0&&age<150) {
this.age = age;
return;
}
throw new RuntimeException("输入错误。。。");
}
❷throw关键字一般用在方法体中,也可以用在代码块中,但如果代码块中抛出的异常对象是由检查时异常创建的,则必须使用try-catch进行处理
public void setAge(int age){
if(age>0&&age<150) {
this.age = age;
return;
}
try {
throw new RuntimeException("输入错误。。。");
} catch (Exception e) {
e.printStackTrace();
}
}
❸使用throw抛出异常对象如果没有try-catch捕获该异常对象,则该抛出异常对象语句执行后其所在方法结束执行。
Student stu=new Student();
stu.setAge(1000);
System.out.println(stu.getAge());//这里就不会输出
❹throws用于声明方法可能抛出的异常,其后为异常类,可以有多个,异常类之间用英文逗号间隔
作用:当方法体中的throw关键字抛出有检查时异常创建的对象时,如果该异常对象在抛出的同时已经通过try-catch进行了处理,则可以不使用throws,否则必须使用throws抛出创建该对象的异常类或其父类。
public void setAge(int age) throws Exception{
if(age>0&&age<150) {
this.age = age;
return;
}
throw new Exception("输入错误。。。");
}
❺当调用的方法抛出了检查时异常时,此时上抛的异常类可以是调用方法时方法抛出的异常类也可以是其父类。
public static void main() throws Exception {
Student stu=new Student();
stu.setAge(1500);
System.out.println(stu.getAge());
}
public void setAge(int age) throws Exception{
if(age>0&&age<150) {
this.age = age;
return;
}
throw new Exception("输入错误。。。");
}
❻throw与throws的区别:
抛出的东西不同:throw抛出的是具体的异常对象,而throws抛出的是抽象的异常类;
使用位置不同:throw一般用在方法体中,也可用在代码块中,但是如果抛出的是检查时异常类创建的对象,则必须使用try-catch自行处理;throws只能用在方法声明括号后面;
四、自定义异常:
自定义异常类继承已有运行时异常类,然后在定义私有方法。
class AgeException extends RuntimeException{
public AgeException(String message) {
super(message);
}
}
public void setAge(int age) {
if(age>0&&age<150) {
this.age = age;
return;
}
throw new AgeException("输入错误。。。");
}
class AgeException extends Exception{
public AgeException(String message) {
super(message);
}
}
如果继承Exception,如果调用方法不用try、catch…捕获时则要连续抛出异常
public class LianDemo {
//第二次throws抛出
public static void main(String[] args) throws AgeException {
Student stu=new Student();
stu.setAge(1500);
System.out.println(stu.getAge());
}
}
//第一次throws抛出
public void setAge(int age) throws AgeException {
if(age>0&&age<150) {
this.age = age;
return;
}
throw new AgeException("输入错误。。。");//
}
五、问题点:
1>两个输出不同级,这里可以输出。第一个捕获异常后,继续输出。
try {
try {
System.out.println(1/0);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("两个输出不同级");
} catch (Exception e) {
e.printStackTrace();
}
2>两个输出同级别,这里第一行捕获异常后,第二行不会输出。
try {
System.out.println(1/0);
System.out.println("两个输出同级别");
} catch (Exception e) {
e.printStackTrace();
}
3>finally在有return关键字时会先执行finally里的内容载执行return;(当然System.exit(0)除外)。
try {
System.out.println(1/0);
} catch (Exception e) {
e.printStackTrace();
return;
}finally {
System.out.println("return之后还会执行finally");
}
4>Log4j
1、是Apache的一个开源项目,通过使用Log4j,可以控制日志信息格式及其输送目的地(控制台、文件、数据库等),方便后期查找系统运行期间出现的问题,进而便于维护系统。
Logger logger=Logger.getLogger(ExceptionDemo.class);
int i=0;
while (true) {
try {
System.out.println(1 / 0);
} catch (Exception e) {
logger.debug(i+","+e.getMessage(), e);
}
i++;
}
2、Log4j里的四个级别依次从大到小为debug、info、warn、error。
Logger logger=Logger.getLogger(ExceptionDemo.class);
try {
System.out.println(1 / 0);
} catch (Exception e) {
logger.debug("debug"+e.getMessage(), e);
logger.info("info"+e.getMessage(), e);
logger.warn("warn"+e.getMessage(), e);
logger.error("error"+e.getMessage(), e);
}
3、log4j文档
#DEBUG\u8BBE\u7F6E\u8F93\u51FA\u65E5\u5FD7\u7EA7\u522B\uFF0C\u7531\u4E8E\u4E3ADEBUG\uFF0C\u6240\u4EE5ERROR\u3001WARN\u548CINFO \u7EA7\u522B\u65E5\u5FD7\u4FE1\u606F\u4E5F\u4F1A\u663E\u793A\u51FA\u6765
log4j.rootLogger=DEBUG,Console,RollingFile
//将日志信息输出到控制台
#\u5C06\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u5230\u63A7\u5236\u53F0
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern= [%-5p]-[%d{yyyy-MM-dd HH:mm:ss}] -%l -%m%n
//将日志信息输出到操作系统D盘根目录下的log.log文件中
#\u5C06\u65E5\u5FD7\u4FE1\u606F\u8F93\u51FA\u5230\u64CD\u4F5C\u7CFB\u7EDFD\u76D8\u6839\u76EE\u5F55\u4E0B\u7684log.log\u6587\u4EF6\u4E2D
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.RollingFile.File=D://log.log
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n
//控制时间,可间接性产生新的日志文件
#\u6BCF\u5929\u4EA7\u751F\u4E00\u4E2A\u65E5\u5FD7\u6587\u4EF6(RollingFile)
log4j.appender.RollingFile=org.apache.log4j.DailyRollingFileAppender
#\u5F53\u5929\u7684\u65E5\u5FD7\u6587\u4EF6\u5168\u8DEF\u5F84
log4j.appender.RollingFile.File=d:/logs/sirius.log
#\u670D\u52A1\u5668\u542F\u52A8\u65E5\u5FD7\u662F\u8FFD\u52A0\uFF0Cfalse\uFF1A\u670D\u52A1\u5668\u542F\u52A8\u540E\u4F1A\u751F\u6210\u65E5\u5FD7\u6587\u4EF6\u628A\u8001\u7684\u8986\u76D6\u6389
log4j.appender.RollingFile.Append=true
#\u65E5\u5FD7\u6587\u4EF6\u683C\u5F0F
log4j.appender.RollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.RollingFile.layout.ConversionPattern=%d [%t] %-5p %-40.40c %X{traceId}-%m%n
log4j.appender.RollingFile.Threshold=DEBUG
#\u8BBE\u7F6E\u6BCF\u5929\u751F\u6210\u4E00\u4E2A\u6587\u4EF6\u540D\u540E\u6DFB\u52A0\u7684\u540D\u79F0,\u5907\u4EFD\u540D\u79F0\uFF1Asirius.log.\u5E74\u6708\u65E5\u65F6\u5206.log
log4j.appender.RollingFile.DatePattern='.'yyyy-MM-dd-HH-mm'.log'
4、SLF4j,即简单日志门面(Simple Logging Facade for Java),它和Log4j一起使用提高了日志信息操作效率
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
private static Logger logger = LoggerFactory.getLogger(Test.class);
public static void main(String[] args) {
try {
System.out.println(1/0);
} catch (Exception e) {
logger.error(e.getMessage(),e);
}
}
}