java异常讲解和处理

来源:互联网 发布:网络监控存储 编辑:程序博客网 时间:2024/06/02 04:29
一.异常体系图。




二.先来认识下何为异常。
     异常:就是程序运行中出现的不正常的情况.
     异常的由来:问题也是现实生活中的一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象,其实异常就是java对不正常情况描述后的对象体现.   


三.异常的分类。
     * Error异常
       Error这个单词翻译是“错误的意思”,它代表出现严重的问题,一出现就是致命的会造成服务器宕机,数据库崩溃等,而且对于Error一般不编写针对性的代码对其进行处理。   
     *Exception异常
       Exception这个单词翻译是“异常的意思”,它代表非严重的问题,如果出现可以用针对性的处理方式进行处理
        列如:A.ry…catch…finally
                 B.throws抛异常


四.JVM是如何处理异常。
     1.main函数收到这个问题时,有两种处理方式:
        a:自己将该问题处理,然后继续运行,一般在编译出问题的上面写上A.try…catch…finally  B.throws抛异常,直接自己处理。
        b:自己没有针对的处理方式,只有交给调用main的jvm来处理
           * jvm有一个默认的异常处理机制,就将该异常进行处理.

           * 并将该异常的名称,异常的信息.异常出现的位置打印在了控制台上,同时将程序停止运行

五.异常的处理方式。
*先放源码:
实体类:
public class Person {
private String name;
private int age;
public String getName(){
   return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age){
   if (age < 0 ) {
    throw new IllegalArgumentException("age is invalid");
   }
   this.age = age;
}
}
测试:
public class abc {
@Test
public void aaa(){
Person person = new Person();
person.setAge(-1);
}
}

*1.try…catch…finally方式
public class abc {
@Test
public void aaa(){
Person person = new Person();
try {
person.setAge(-1);
} catch (Exception e) {

}
}

*2.hrows抛异常
public class abc {
@Test
public void aaa() throws Exception{
FileInputStream fis = new FileInputStream("xxx.txt");
fis.close();
}
}

*3.junit annotation方式 

JUnit中提供了一个expected的annotation来检查异常。

123456
    @Test(expected = IllegalArgumentException.class)    public void shouldGetExceptionWhenAgeLessThan0() {        Person person = new Person();        person.setAge(-1);    }
这种方式看起来要简洁多了,但是无法检查异常中的消息。


*4.ExpectedException方式  
JUnit7以后提供了一个叫做ExpectedException的Rule来实现对异常的测试。

123456789101112
    @Rule    public ExpectedException exception = ExpectedException.none();    @Test    public void shouldGetExceptionWhenAgeLessThan0() {        Person person = new Person();        exception.expect(IllegalArgumentException.class);        exception.expectMessage(containsString("age is invalid"));        person.setAge(-1);    }
这种方式既可以检查异常类型,也可以验证异常中的消息。


*5.catch-exception库
     有个catch-exception库也可以实现对异常的测试。
     首先引用该库。
pom.xml

123456
        <dependency>            <groupId>com.googlecode.catch-exception</groupId>            <artifactId>catch-exception</artifactId>            <version>1.2.0</version>            <scope>test</scope> <!-- test scope to use it only in tests -->        </dependency>
然后这样书写测试。
12345678
    @Test    public void shouldGetExceptionWhenAgeLessThan0() {        Person person = new Person();        catchException(person).setAge(-1);        assertThat(caughtException(),instanceOf(IllegalArgumentException.class));        assertThat(caughtException().getMessage(), containsString("age is invalid"));    }
这样的好处是可以精准的验证异常是被测方法抛出来的,而不是其它方法抛出来的。
catch-exception库还提供了多种API来进行测试。
先加载fest-assertion库。
12345
        <dependency>            <groupId>org.easytesting</groupId>            <artifactId>fest-assert-core</artifactId>            <version>2.0M10</version>        </dependency>
然后可以书写BDD风格的测试。

234567891011121
    @Test    public void shouldGetExceptionWhenAgeLessThan0() {        // given        Person person = new Person();        // when        when(person).setAge(-1);        // then        then(caughtException())                .isInstanceOf(IllegalArgumentException.class)                .hasMessage("age is invalid")                .hasNoCause();    }

如果喜欢Hamcrest风格的验证风格的话,catch-exception也提供了相应的Matcher API。

1234567891011121314
    @Test    public void shouldGetExceptionWhenAgeLessThan0() {        // given        Person person = new Person();        // when        when(person).setAge(-1);        // then        assertThat(caughtException(), allOf(                instanceOf(IllegalArgumentException.class)                , hasMessage("age is invalid")                ,hasNoCause()));    }

五.编译期异常和运行期异常的区别。     
1.运行期异常对应Exception的子类RuntimeException及其子类的实例。一般出错就是你的逻辑有问题相互矛盾,需要程序员自己去修改。或者用try…catch…,抛出异常
2.编译期异常就是你编写代码时出现的红色警告提示,java程序必须显示处理,否则程序就会报Error异常(也就是重大错误),无法通过编译。需要我们修改代码或者
   列如:A.try…catch…finally
            B.throws抛异常

六.自定异常的概述和基本使用方法。
public class Demo8_Exception {
  /* A:为什么需要自定义异常
   * 通过名字区分到底是神马异常,有针对的解决办法 
   * 举例:人的年龄
   * B:自定义异常概述
   * 继承自Exception
   * 继承自RuntimeException
   * C:案例演示
   * 自定义异常的基本使用
   */
 class AgeOutOfBoundsException extends Exception {
  public AgeOutOfBoundsException() {
  super();
  }
  public AgeOutOfBoundsException(String message) {
  super(message);
  } 
 }
测试类:
 public class Demo6_Exception {
  /*A:throws的方式处理异常
  * 定义功能方法时,需要把出现的问题暴露出来让调用者去处理
  * 那么就通过throws在方法上标识。
  * B:案例演示
  * 举例分别演示编译时异常和运行时异常的抛出
  * 编译时异常的抛出必须对其进行处理
  * 运行时异常的抛出可以处理也可以不处理
  * @throws Exception 
  */
 public static void main(String[] args) throws Exception {
  Person p = new Person();
  p.setAge(-17);
  System.out.println(p.getAge());
  }
 class Person {
  private String name;
  private int age;
  public Person() {
  super();  
  }
 public Person(String name, int age) {
  super();
  this.name = name;
  this.age = age;
  }
 public String getName() {
  return name;
  }
 public void setName(String name) {
  this.name = name;
 }
public int getAge() {
  return age;
 }

public void setAge(int age) throws AgeOutOfBoundsException {
 if(age >0 && age <= 150) {
  this.age = age;
  }else {
  throw new AgeOutOfBoundsException("年龄非法");
  }
  }




1 0