欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java异常处理实例教程

程序员文章站 2024-03-09 14:02:11
1、什么是异常? 首先,让我们来看看下图的例子: 在这个例子中,存在的错误码由除以0的结果。由于除以0而导致异常: arithmeticexception h...

1、什么是异常?
首先,让我们来看看下图的例子:
在这个例子中,存在的错误码由除以0的结果。由于除以0而导致异常: arithmeticexception
helloexception.java

package com.yiibai.tutorial.exception;

public class helloexception {

  public static void main(string[] args) {

    system.out.println("three");

    // this division no problem.
    int value = 10 / 2;

    system.out.println("two");

    // this division no problem.
    value = 10 / 1;

    system.out.println("one");
    
    // this division has problem, divided by 0.
    // an error has occurred here.
    value = 10 / 0;

    // and the following code will not be executed.
    system.out.println("let's go!");

  }

}

运行这个例子,得到的结果是:

Java异常处理实例教程

可以看到控制台屏幕上的通知。错误通知是很清楚的,包括代码行的信息。
让我们通过下图中的流程看看下面的程序:

  • 程序从(1),(2)至(5)步骤正常运行。
  • 在步骤(6)程序除以0。
  • 程序跳转出 main 方法后,而(7)代码行还没有被执行。

Java异常处理实例教程

我们将修改上述实施例的代码。

hellocatchexception.java

package com.yiibai.tutorial.exception;

public class hellocatchexception {

  public static void main(string[] args) {

    system.out.println("three");

    // this division no problem.
    int value = 10 / 2;

    system.out.println("two");

    // this division no problem.
    value = 10 / 1;

    system.out.println("one");

    try {
      // this division has problem, divided by 0.
      // an error has occurred here.      
      value = 10 / 0;

      // and the following code will not be executed.
      system.out.println("value =" + value);

    } catch (arithmeticexception e) {

      // the code in the catch block will be executed
      system.out.println("error: " + e.getmessage());

      // the code in the catch block will be executed
      system.out.println("ignore...");

    }

    // this code is executed
    system.out.println("let's go!");

  }

}

运行示例结果:

three

two

one

error: / by zero

ignore...

let's go!

我们将按以下实例图像的流程来解释下面的程序。

  • 步骤(1)至(5)是完全正常的。
  • 异常发生在步骤(6),除以0出现了问题。
  • 它立即跳到catch块执行命令,步骤(7)被跳过。
  • 步骤(8),(9)被执行。
  • 步骤(10)被执行。

Java异常处理实例教程

2、 异常层次结构
这是java异常的分层图的模型。

最高的类是:throwable

两个直接子类是 error 和 exception。

在异常转移有一个runtimeexception子类,包括java中的编译时未检查异常。检查并取消检查在编译时,在下一部分的实施示例中说明。

注意:您的类应该从两个分支:error或exception继承,而不是直接从throwable继承。

Java异常处理实例教程

当一个动态链接失败,或在虚拟机的一些其他的“硬”故障发生时,虚拟机引发这个错误。典型的java程序不捕获错误,所以java程序都不会抛出任何错误。大多数程序抛出并捕获从exception类派生的对象。异常指示出现了一个问题,但是这些问题并不是严重系统性问题。你写的大多数程序将会抛出和捕获异常。

exception类在java包定义了许多子类。这些子类指明不同类型的可能会发生异常。 例如,negativearraysizeexception表明程序试图创建一个大小为负的数组。

一个导演的子类在java语言中的特殊含义: runtimeexception类表示java虚拟机中发生(在运行期间)的异常。运行时异常的一个例子是nullyiibaierexception异常,其中,当一种方法试图通过一个空引用来访问对象的成员时就会引发。 nullyiibaierexception 可以在任何地方出现某个程序试图取消引用一个对象的引用。经常检查异常捕获的好处远远超过它的成本。

由于运行时异常是无所不在的,在试图捕获或指定所有的时间是徒劳的作法(不可读和不可维护的代码), 编译器允许运行时异常去未捕获和指定。
java包定义几个runtimeexception类。您可以捕获这些异常,就像其他异常。但是并不需要一种方法来指定它抛出运行时异常。此外可以创建自己的runtimeexception子类。 运行时异常 - 下面讨论包含何时以及如何使用运行时异常进行了深入探讨。 3、使用try-catch处理异常

编写从exception 继承的类。

Java异常处理实例教程

ageexception.java

package com.yiibai.tutorial.exception.basic;

public class ageexception extends exception {

  public ageexception(string message) {
    super(message);
  }

}
tooyoungexception.java
package com.yiibai.tutorial.exception.basic;

public class tooyoungexception extends ageexception {

 public tooyoungexception(string message) {
   super(message);
 }

}

toooldexception.java

package com.yiibai.tutorial.exception.basic;

public class toooldexception extends ageexception {

 public toooldexception(string message) {
   super(message);
 }

}

以及ageutils类检查年龄的检查静态方法。
ageutils.java

package com.yiibai.tutorial.exception.basic;

public class ageutils {

 
  // this method checks the age.
  // if age is less than 18, the method will throw an exception tooyoungexception
  // if age greater than 40, the method will throw an exception toooldexception
  public static void checkage(int age) throws tooyoungexception,
      toooldexception {
    if (age < 18) {

      // if age is less than 18, an exception will be thrown
      // this method ends here.
      throw new tooyoungexception("age " + age + " too young");
    } else if (age > 40) {

      // if age greater than 40, an exception will be thrown.
      // this method ends here.
      throw new toooldexception("age " + age + " too old");
    }

    // if age is between 18-40.
    // this code will be execute.
    system.out.println("age " + age + " ok!");
  }
}

检查异常和未经检查的异常:
ageexception是exception,toooldexception的子类和tooyoungexception2是 ageexception直接子类,所以它们是“checked exception”
在ageutils.checkage(int)方法已经抛出异常,需要通过关键字“throws”,列出它们的方法声明。或者可以声明抛出更多的级别。
在使用 ageutils.checkage(int) 位置也必须进行处理,以捕获异常,或继续抛出去。

Java异常处理实例教程

"checked exception" 是由 "java compiler"来检查。

Java异常处理实例教程

有两个选择:

Java异常处理实例教程

trycatchdemo1.java

package com.yiibai.tutorial.exception.basic;

public class trycatchdemo1 {

  public static void main(string[] args) {


    system.out.println("start recruiting ...");
    // check age
    system.out.println("check your age");
    int age = 50;

    try {

      ageutils.checkage(age);

      system.out.println("you pass!");

    } catch (tooyoungexception e) {

      // do something here ..
      system.out.println("you are too young, not pass!");
      system.out.println(e.getmessage());

    } catch (toooldexception e) {

      // do something here ..
      system.out.println("you are too old, not pass!");
      system.out.println(e.getmessage());

    }

  }
}

在下面的例子中,我们将通过父类捕获异常(超exception类)。
trycatchdemo2.java

package com.yiibai.tutorial.exception.basic;

public class trycatchdemo2 {

  public static void main(string[] args) {

    system.out.println("start recruiting ...");
    // check age
    system.out.println("check your age");
    int age = 15;

    try {

      // here can throw toooldexception or tooyoungexception
      ageutils.checkage(age);

      system.out.println("you pass!");

    } catch (ageexception e) {
      
      // if an exception occurs, type of ageexception
      // this catch block will be execute
      system.out.println("your age invalid, you not pass");
      system.out.println(e.getmessage());

    }
  }
}

也可以组不同的异常在块中来处理,如果它们对逻辑程序处理是相同的方式。
trycatchdemo3.java

package com.yiibai.tutorial.exception.basic;

public class trycatchdemo3 {

  public static void main(string[] args) {

    system.out.println("start recruiting ...");
    // check age
    system.out.println("check your age");
    int age = 15;

    try {

      // here can throw toooldexception or tooyoungexception
      ageutils.checkage(age);

      system.out.println("you pass!");

    } catch (tooyoungexception | toooldexception e) {
      // catch multi exceptions in one block.

      system.out.println("your age invalid, you not pass");
      system.out.println(e.getmessage());

    }
  }

}

4、 try-catch-finally
我们已习惯于通过 try-catch 块捕获错误。try-catch-finally 来完全处理异常。

try {

  // do something here

} catch (exception1 e) {

  // do something here

} catch (exception2 e) {

  // do something here

} finally {

  // finally block is always executed
  // do something here

}

trycatchfinallydemo.java

package com.yiibai.tutorial.exception.basic;

public class trycatchfinallydemo {

  public static void main(string[] args) {

    string text = "001234a2";

    int value = tointeger(text);

    system.out.println("value= " + value);

  }

  public static int tointeger(string text) {
    try {

      system.out.println("begin parse text: " + text);

      // an exception can throw here (numberformatexception).
      int value = integer.parseint(text);

      return value;

    } catch (numberformatexception e) {

      
      // in the case of 'text' is not a number.
      // this catch block will be executed.      
      system.out.println("number format exception " + e.getmessage());

      // returns 0 if numberformatexception occurs
      return 0;

    } finally {

      system.out.println("end parse text: " + text);

    }
  }

}

这是程序的流程。 finally块无论什么情况下总会被执行。

Java异常处理实例教程

5、 环绕异常

  • 我们需要一些类参与到这个例子:
  • person: 模拟一个受试者招募到公司的信息:姓名,年龄,性别。
  • genderexception: 性别异常。
  • validateexception: 异常评估求职者。
  • validateutils: 静态方法类综合评价面试者。
  • 如果男性年龄在18-40之间的被认为是有效的。

person.java

package com.yiibai.tutorial.exception.wrap;

public class person {

  public static final string male = "male";
  public static final string female = "female";

  private string name;
  private string gender;
  private int age;

  public person(string name, string gender, int age) {
    this.name = name;
    this.gender = gender;
    this.age = age;
  }

  public string getname() {
    return name;
  }

  public void setname(string name) {
    this.name = name;
  }

  public string getgender() {
    return gender;
  }

  public void setgender(string gender) {
    this.gender = gender;
  }

  public int getage() {
    return age;
  }

  public void setage(int age) {
    this.age = age;
  }
}

genderexception.java

package com.yiibai.tutorial.exception.wrap;

// gender exception.
public class genderexception extends exception {

   public genderexception(string message) {
     super(message);
   }
}

validateexception 类包有其他异常。
validateexception.java

package com.yiibai.tutorial.exception.wrap;

public class validateexception extends exception {
  
  // wrap an exception
  public validateexception(exception e) {
    super(e);
  }

}

validateutils.java

package com.yiibai.tutorial.exception.wrap;

import com.yiibai.tutorial.exception.basic.ageutils;

public class validateutils {

  public static void checkperson(person person) throws validateexception {
    try {

      // check age.
      // valid if between 18-40
      // this method can throw toooldexception, tooyoungexception.    
      ageutils.checkage(person.getage());

    } catch (exception e) {
      
      // if not valid
      // wrap this exception by validateexception, and throw
      throw new validateexception(e);

    }

    // if that person is female, ie invalid.
    if (person.getgender().equals(person.female)) {

      genderexception e = new genderexception("do not accept women");
      throw new validateexception(e);

    }
  }

}

wrapperexceptiondemo.java

package com.yiibai.tutorial.exception.wrap;

public class wrapperexceptiondemo {

  public static void main(string[] args) {
    
    // one participant recruitment.
    person person = new person("marry", person.female, 20);

    try {

      // exceptions may occur here.
      validateutils.checkperson(person);

    } catch (validateexception wrap) {

      // get the real cause.
      // may be tooyoungexception, toooldexception, genderexception
      exception cause = (exception) wrap.getcause();

      if (cause != null) {
        system.out.println("not pass, cause: " + cause.getmessage());
      } else {
        system.out.println(wrap.getmessage());
      }

    }
  }

}

6、runtimeexception和子类 runtimeexception类及其子类都是“未检查的例外”。它不是由java编译器在编译时进行检查。在某些情况下,你可以从这个分支继承编写自己的异常。

下面是属于runtimeexception分支一些类(当然,这还不是全部)。
一些处理这种类型异常的例子:

Java异常处理实例教程

6.1- nullyiibaierexception
这是最常见的异常,通常会导致错误在程序中。异常被抛出,当你调用方法或访问一个空对象的字段。
nullyiibaierexceptiondemo.java

package com.yiibai.tutorial.exception.runtime;

public class nullyiibaierexceptiondemo {

  // for example, here is a method that can return null string.
  public static string getstring() {
    if (1 == 2) {
      return "1==2 !!";
    }
    return null;
  }

  public static void main(string[] args) {

    // this is an object that references not null.
    string text1 = "hello exception";

    // call the method retrieves the string length.
    int length = text1.length();

    system.out.println("length text1 = " + length);

    // this is an object that references null.
    string text2 = getstring();
    
    // call the method retrieves the string length.
    // nullyiibaierexception will occur here.
    // it is an exception occurs at runtime (type of runtimeexception)
    // javac compiler does not force you to use a try-catch block to handle it
    length = text2.length();

    system.out.println("finish!");
  }

}

运行示例的结果:

Java异常处理实例教程

在现实中,像处理其他异常时,可以使用 try-catch 来捕获并处理这个异常。 然而,这是机械的,通常情况下,我们应该检查,以确保在使用它之前,对象不为空值。
您可以更正上面的代码,使其类似于下面的以避免空指针异常:

// this is a null object.
string text2 = getstring();

// check to make sure 'text2' are not null.
// instead of using try-catch.
if (text2 != null) {
 length = text2.length();
}

6.2- arrayindexofboundexception
当您试图访问一个无效的索引的数组元素就会发生此异常。例如,一个数组有10个元素可以访问,但您访问的是索引为20的元素。
arrayindexofboundsexceptiondemo.java

package com.yiibai.tutorial.exception.runtime;

public class arrayindexofboundsexceptiondemo {

  public static void main(string[] args) {

    string[] strs = new string[] { "one", "two", "three" };

    // access to the element has index 0.
    string str1 = strs[0];

    system.out.println("string at 0 = " + str1);

    
    // access to the element has index 5.
    // arrayindexofboundsexception occur here.
    string str2 = strs[5];

    system.out.println("string at 5 = " + str2);

  }

}

为了避免 arrayindexofboundsexception,我们更多的应该是检查数组而不是使用try-catch。

if (strs.length > 5) {
  string str2 = strs[5];
  system.out.println("string at 5 = " + str2);
} else {
  system.out.println("no elements with index 5");
}

以上就是本文的全部内容,希望对大家的学习有所帮助。