什么是异常
异常就是在程序的运行过程中所发生的不正常的事件。在java中,阻止当前方法或作用域的情况,称之为异常。
捕获异常:try,catch,finally
-
把可能出现异常的代码放入try语句块中,并使用catch语句块捕获异常。
-
如果try块中所有语句正常执行完毕,不会发生异常,那么catch块中的所有语句都将会被忽略。
-
如果try语句块在执行过程中遇到异常,并且这个异常与catch中声明的异常类型相匹配,那么在try块中其余剩下的代码都将被忽略。
-
无论是否发生异常,finally块中的代码总能被执行
-
try-catch-finally结构中try块是必需的,catch和finally块为可选,但两者至少须出现其中之一
示例:按照控制台提示输入1~3之间的任一个数字,程序将输出相应的课程名称。无论输入是否正确,均输出"欢迎提出建议"语句
/**
* 课程类
*/
public class Course {
public void course(int num){
switch(num){
case 1:
System.out.println("Java");
break;
case 2:
System.out.println("C#");
break;
case 3:
System.out.println("C++");
break;
default:
System.out.println("输入错误,请正确输入编号");
}
}
}
/**
* 测试类,测试课程类
*/
import java.util.InputMismatchException;
import java.util.Scanner;
import org.apache.log4j.Logger;
public class TestCourse {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入课程编号1~3");
try{
int num = input.nextInt();
Course course = new Course();
course.course(num);
}catch(InputMismatchException x){
System.out.println("输入格式错误");
x.printStackTrace();
}finally{
System.out.println("欢迎提出建议");
}
}
}
如果这里故意输出非正常数字,而输出一字符串,则catch将捕捉异常,输出错误信息,结果如下:
Java常见异常类型:
抛出异常throw和throws
throw和throws的区别:
- throw是语句抛出一个异常。
语法:throw (异常对象);
throw e;
- throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常)
语法:(修饰符)(方法名)([参数列表])[throws(异常类)]{…}
public void doA(int a) throws Exception1,Exception3{…}
下面通过示例来展现:在 setAge(int age)中对年龄进行判断,如果年龄介于1到100直接赋值,否则抛出异常。
/**
* 人类
*/
public class Person{
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setAge(int age) throws Exception{
if (age <= 100 && age >0) {
this.age = age;
}else {
throw new Exception("年龄是1~100");
}
}
public void pint(){
System.out.println("姓名是"+name+",性别是:"+sex+",年龄是:"+age);
}
}
public class TestPerson{
public static void main(String[] args) {
Age age = new Age();
age.setName("小小");
try {
age.setSex("男");
age.setAge(101);
age.pint();
} catch (Exception e) {
e.printStackTrace();
}
}
}
既然抛出了异常,就需要捕获异常,不然就会报错,提示信息如下:
这个时候就需要用try-catch来捕获异常,也可以点击错误信息的两个选项,下面就来演示点击第二个选项来用try-catch来捕获异常
/**
* 测试类,测试人类
*/
public class TestPerson {
public static void main(String[] args) {
Person person = new Person();
person.setName("小小");
try {
person.setSex("男");
person.setAge(101);
person.pint();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在这里故意给年龄赋一个不正确的值,抛出异常,输出错误信息,结果如下:
总结:
throw和throws的区别表现在以下三个方面:
-
作用不同:throw用于在程序中抛出异常;throws用于声明在该方法内抛出了异常。
-
使用的位置不同:throw位于方法体内部,可以作为单独语句使用;throws必须跟在方法参数列表的后面,不能单独使用。
-
内容不能:throws抛出一个异常对象,而且只能是一个;throws后面跟异常类,而且可以跟多个异常类
Log4j是什么?
log4j是Apache的一个开放源代码的项目,通过使用log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
此外,通过log4j其他的语言接口,您可以在C、C++、.Net、PL/SQL程序中使用log4j,其语法和用法与在Java程序中一样,使得多语言分布式系统得到一个统一一致的日志组件模块。而且,通过使用各种第三方扩展,您可以很方便地将Log4j集成到J2EE、JINI甚至是SNMP应用中。
记录日志信息的作用?
1)监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作;
2)跟踪代码运行时轨迹,作为日后审计的依据;
3)担当集成开发环境中的调试器的作用,向文件或控制台打印代码的调试信息。
使用Log4j框架的作用通俗的解释:
能够控制日志信息想往哪里打就往哪里打,比如:控制台、文件、邮箱、数据库等等。
能够控制日志信息想怎么打就怎么打,比如:我想要打印时间、程序的名称、程序的方法名、程序的行号、线程的名称等等。
能够控制日志信息想打什么打什么,不想打的就不打,日志信息是分级别的,有时候我只想看错误的信息或者警告的信息,有时候我想看到所有的信息我想调试程序等等。
为什么要用log4j?
通常,我们写代码的过程中,免不了要输出各种调试信息。在没有使用任何日志工具之前,都会使用 System.out.println 来做到。 这么做直观有效,但是有一系列的缺点:
-
不知道这句话是在哪个类,哪个线程里出来的。
-
不知道什么时候前后两句输出间隔了多少时间。
-
无法关闭调试信息,一旦System.out.println多了之后,到处都是输出,增加定位自己需要信息的难度。等等
如图所示,光溜溜的出现这么些输出信息出来:
package log4j;
public class TestLog4j {
public static void main(String[] args) throws InterruptedException {
System.out.println("跟踪信息");
System.out.println("调试信息");
System.out.println("输出信息");
System.out.println("警告信息");
System.out.println("错误信息");
System.out.println("致命信息");
}
}
为了应对这种情况,我们使用Log4j来进行日志输出。看下面的实例
log4j入门实例
- 新建一个Java工程Log4jTest,导入包log4j-1.2.17.jar,整个工程最终目录如下:
- src同级创建并设置log4j.properties
### 设置###
log4j.rootLogger = debug,stdout,D,E
### 输出信息到控制抬 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 输出DEBUG 级别以上的日志到=/home/hao/Desktop/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = /home/hao/Desktop/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出ERROR 级别以上的日志到=/home/hao/Desktop/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =/home/hao/Desktop/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
- 设置日志内容,实践出真知
package com.log4j;
import org.apache.log4j.Logger;
/**
1. log4j入门实例
2. @author hao
*/
public class TestLog4j {
// 得到记录器并读取配置文件 -- 基于类的名称获取日志对象
private static Logger logger = Logger.getLogger(TestLog4j.class);
public static void main(String[] args) {
// 插入记录信息(格式化日志信息)
// 记录debug级别的信息
logger.debug("调试信息.");
// 记录info级别的信息
logger.info("输出信息.");
// 记录error级别的信息
logger.error("错误信息.");
// 记录warn级别的信息
logger.warn("警告信息.");
logger.trace("跟踪信息");
logger.fatal("致命信息");
}
}
输出结果:
1 ) 首先是控制台的信息:
2 ) 输出的文件: