Java - 例外処理


■ページ目次

Top

エラーが発生したときの動作

Top
例外
Top
何もしない
Top
発生した関数を呼び出したメソッドに対処を依頼
Top
発生したメソッドが自分で対処
Top

エラーの種類

Top

例外オブジェクト

例外クラス
図 例外クラス
■実習
  1. つぎの"Exception30.java"をコンパイル・実行してください。実行するとき、つぎのような条件をつけてください。
    1. 引数を指定しない
    2. 引数に文字を指定
    3. 引数に0を指定
    4. 引数に0以外の整数を指定
    1. public class Exception30 {
    2. public static void main(String[] args) {
    3. System.out.println("*** start ***");
    4. int a = Integer.parseInt(args[0]);
    5. System.out.println(100 / a);
    6. System.out.println("*** end ***");
    7. }
    8. }

    □ 実行結果

    $ java Exception30
    *** start ***
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
            at Exception30.main(Exception30.java:4)
    
    $ java Exception30 Hello
    *** start ***
    Exception in thread "main" java.lang.NumberFormatException: For input string: "Hello"
            at java.lang.NumberFormatException.forInputString(Unknown Source)
            at java.lang.Integer.parseInt(Unknown Source)
            at java.lang.Integer.parseInt(Unknown Source)
            at Exception30.main(Exception30.java:4)
    
    $ java Exception30 0
    *** start ***
    Exception in thread "main" java.lang.ArithmeticException: / by zero
            at Exception30.main(Exception30.java:5)
    
    $ java Exception30 20
    *** start ***
    5
    *** end ***
    
Top

独自の例外をスローする

Top

例外をキャッチせずにスローする

Top

複数のcatch文を使用する

■例題
  1. つぎの"Exception50.java"をコンパイル・実行してください。実行するとき、つぎのような条件をつけてください。
    1. 引数を指定しない
    2. 引数に0を指定
    3. 引数に文字を指定
    1. public class Exception50 {
    2. public static void main(String[] args) {
    3. System.out.println("*** start ***");
    4. int a = 0;
    5. try{
    6. a = Integer.parseInt(args[0]);
    7. System.out.println(100 / a);
    8. } catch (ArrayIndexOutOfBoundsException e) {
    9. System.out.print("*** 不正なインデックス *** ");
    10. System.out.println(e.getMessage());
    11. } catch (Exception e) {
    12. System.out.println("*** Exception ***");
    13. e.printStackTrace();
    14. }
    15. System.out.println("*** end ***");
    16. }
    17. }

    □ 実行結果

    $ java Exception50
    *** start ***
    *** 不正なインデックス *** 0
    *** end ***
    
    $ java Exception50 Hello
    *** start ***
    *** Exception ***
    java.lang.NumberFormatException: For input string: "Hello"
            at java.lang.NumberFormatException.forInputString(Unknown Source)
            at java.lang.Integer.parseInt(Unknown Source)
            at java.lang.Integer.parseInt(Unknown Source)
            at Exception50.main(Exception50.java:6)
    *** end ***
    
    $ java Exception50 0
    *** start ***
    *** Exception ***
    java.lang.ArithmeticException: / by zero
            at Exception50.main(Exception50.java:7)
    *** end ***
    
    $ java Exception50 20
    *** start ***
    5
    *** end ***
    
Top

finally 文

Top
商品管理システムに例外を導入
  1. つぎの商品クラス"Product.java"では、商品定価にint型に変換不可能な文字列が指定された場合、スタック・トレースを表示して、定価には0を設定します。
    1. // 1211 = 1201
    2. // package product;
    3. // 商品クラスです。
    4. // ひとつの商品に対するフィールドやフィールドを操作するためのメソッドを
    5. // 提供しています。
    6. public class Product extends AbstractProduct {
    7. private int price; // 商品定価
    8. // 商品クラスのコンストラクター。
    9. public Product(String code, String name, int price) {
    10. setCode(code);
    11. setName(name);
    12. setPrice(price);
    13. }
    14. // 商品クラスのコンストラクター。
    15. public Product(String code, String name, String price) {
    16. setCode(code);
    17. setName(name);
    18. setPrice(price);
    19. }
    20. // 商品定価に値を設定します。
    21. public void setPrice(int price) {
    22. if (price < 0) {
    23. this.price = 0;
    24. return;
    25. }
    26. this.price = price;
    27. }
    28. // 商品定価に値を設定します。
    29. public void setPrice(String price) {
    30. try {
    31. setPrice(Integer.parseInt(price));
    32. } catch (NumberFormatException e) {
    33. setPrice(0);
    34. e.printStackTrace();
    35. } catch (Exception e) {
    36. setPrice(0);
    37. e.printStackTrace();
    38. }
    39. }
    40. // 商品定価の値を取得します。
    41. public int getPrice() {
    42. return this.price;
    43. }
    44. }
  2. つぎの"TestProduct.java"を作成し、実行してください。
    1. // 1211
    2. // package application;
    3. // import product.*;
    4. // 商品クラスをテストするクラスです。
    5. public class TestProduct {
    6. public static void main(String[] args) {
    7. Product p1 = new Product(args[0], args[1], args[2]);
    8. System.out.println("商品のインスタンスを生成しました。 p1 = " + p1);
    9. System.out.println(" code = " + p1.getCode());
    10. System.out.println(" name = " + p1.getName());
    11. System.out.println(" price = " + p1.getPrice());
    12. }
    13. }

    □ 実行結果

    $ java TestProduct A001 パソコン 188000
    商品のインスタンスを生成しました。 p1 = product.Product@1b90b39
       code = A001
       name = パソコン
      price = 188000
    
    $ java TestProduct A001 パソコン 188ooo
    java.lang.NumberFormatException: For input string: "188ooo"
            at java.lang.NumberFormatException.forInputString(NumberFormatException.
    java:48)
            at java.lang.Integer.parseInt(Integer.java:435)
            at java.lang.Integer.parseInt(Integer.java:476)
            at product.AbstractProduct.setPrice(AbstractProduct.java:42)
            at product.Product.(Product.java:23)
            at application.TestProduct.main(TestProduct.java:7)
    商品のインスタンスを生成しました。 p1 = product.Product@18fe7c3
       code = A001
       name = パソコン
      price = 0
    
  3. あわせて、"DiscountProduct.java"のsetDiscount(String)メソッドと、"SetProduct.java"のsetDiscount(String)メソッドにも、上記と同様に、try-catchをつけます。
    1. // 1211
    2. // package product;
    3. // 割引商品クラスです。
    4. // ひとつの商品に対するフィールドやフィールドを操作するためのメソッドを
    5. // 提供しています。
    6. public class DiscountProduct extends Product implements DiscountInterface {
    7. private int discount; // 商品割引率
    8. // 割引商品クラスのコンストラクター。
    9. public DiscountProduct(String code, String name, int price) {
    10. this(code, name, price, 0);
    11. }
    12. // 割引商品クラスのコンストラクター。
    13. public DiscountProduct(String code, String name, String price) {
    14. this(code, name, price, "0");
    15. }
    16. // 割引商品クラスのコンストラクター。
    17. public DiscountProduct(String code, String name, int price, int discount) {
    18. super(code, name, price);
    19. setDiscount(discount);
    20. }
    21. // 割引商品クラスのコンストラクター。
    22. public DiscountProduct(String code, String name, String price, String discount) {
    23. super(code, name, price);
    24. setDiscount(discount);
    25. }
    26. // 商品割引率に値を設定します。
    27. public void setDiscount(int discount) {
    28. if (discount < 0 || discount > 100) {
    29. this.discount = 0;
    30. return;
    31. }
    32. this.discount = discount;
    33. }
    34. // 商品割引率に値を設定します。
    35. public void setDiscount(String discount) {
    36. try {
    37. setDiscount(Integer.parseInt(discount));
    38. } catch (NumberFormatException e) {
    39. setDiscount(0);
    40. e.printStackTrace();
    41. } catch (Exception e) {
    42. setDiscount(0);
    43. e.printStackTrace();
    44. }
    45. }
    46. // 商品割引率の値を取得します。
    47. public int getDiscount() {
    48. return this.discount;
    49. }
    50. // 商品の売値の値を取得します。
    51. public int getPrice() {
    52. return (int)(super.getPrice() * (1 - discount / 100.0));
    53. }
    54. }
    1. // 1211
    2. // package product;
    3. // セット商品クラスです。
    4. // ひとつまたは複数の商品を集めて、割引したものをセット商品として扱います。
    5. // セット商品に対するフィールドやフィールドを操作するためのメソッドを
    6. // 提供しています。
    7. public class SetProduct extends AbstractProduct implements DiscountInterface {
    8. private int discount; // セット商品割引率
    9. private AbstractProduct[] products; // セット商品リスト
    10. // セット商品クラスのコンストラクター。
    11. public SetProduct(String code, String name, int discount, AbstractProduct[] products) {
    12. setCode(code);
    13. setName(name);
    14. setDiscount(discount);
    15. setProducts(products);
    16. }
    17. // 商品の売値の値を取得します。
    18. public int getPrice() {
    19. int price = 0;
    20. for (int i = 0; i < products.length; i++) {
    21. price += products[i].getPrice();
    22. }
    23. return (int)(price * (1 - discount / 100.0));
    24. }
    25. // 商品割引率に値を設定します。
    26. public void setDiscount(int discount) {
    27. if (discount < 10 || discount > 100) {
    28. this.discount = 0;
    29. return;
    30. }
    31. this.discount = discount;
    32. }
    33. // 商品割引率に値を設定します。
    34. public void setDiscount(String discount) {
    35. try {
    36. setDiscount(Integer.parseInt(discount));
    37. } catch (NumberFormatException e) {
    38. setDiscount(0);
    39. e.printStackTrace();
    40. } catch (Exception e) {
    41. setDiscount(0);
    42. e.printStackTrace();
    43. }
    44. }
    45. // 商品割引率の値を取得します。
    46. public int getDiscount() {
    47. return discount;
    48. }
    49. // 商品割引率に値を設定します。
    50. public void setProducts(AbstractProduct[] products) {
    51. this.products = products;
    52. }
    53. }
Top

■(参考) 例外とメソッドのオーバーライド

Top

inserted by FC2 system