1. ホーム
  2. java

[解決済み] Javaによる真の解決策:2つの文字列から2つの数値をパースし、その合計を返す

2023-05-23 11:05:24

質問

かなり愚問です。コードを考えると

public static int sum(String a, String b) /* throws? WHAT? */ {
  int x = Integer.parseInt(a); // throws NumberFormatException
  int y = Integer.parseInt(b); // throws NumberFormatException
  return x + y;
}

良いJavaかどうか、教えていただけませんか?私が言っているのは NumberFormatException が未チェックの例外であることです。あなたは を持っていない の一部として指定する必要があります。 sum() のシグネチャの一部として指定する必要はありません。さらに、私が理解する限り、チェックされていない例外のアイデアは、プログラムの実装が正しくないことを知らせるためだけであり、さらに、チェックされていない例外をキャッチすることは、以下のようになるので、悪いアイデアです。 実行時に悪いプログラムを修正する .

誰か明確にしてくれませんか。

  1. 私は NumberFormatException をメソッドのシグネチャの一部として指定します。
  2. チェックした例外を自分で定義する必要がある ( BadDataException ) を定義し NumberFormatException をメソッド内で処理し、それを BadDataException .
  3. 自分でチェックした例外を定義しておかないと( BadDataException ) を定義し、正規表現のような方法で両方の文字列を検証して BadDataException を投げます。
  4. あなたのアイデアですか?

更新 :

オープンソースのフレームワークで、何らかの理由で使うべきものではないと想像してください。メソッドのシグネチャを見て、「よし、これは投げないぞ」と思ったとします。そして、ある日、例外が発生しました。それは正常ですか?

アップデート2 :

いくつかのコメントで、私の sum(String, String) は悪いデザインだと言うコメントがあります。私も全く同感なのですが、良いデザインであれば、本来の問題は発生しないと考えている方に、ここで余計な質問をさせていただきます。

問題の定義は次のようなものです:データソースがあり、そこには数字が String s. このソースは XML ファイル、Web ページ、2 つの編集ボックスがあるデスクトップ ウィンドウなど、何でもかまいません。

あなたの目標は、これらの2つの String を受け取り、それらを int に変換し、「合計はxxx"です」というメッセージボックスを表示します。

どのようなアプローチで設計/実装しても、次のようになります。 内部機能として次の 2 つのポイントがあります。 :

  1. 変換する場所 String から int
  2. 2を足したところ int s

私の元の投稿の第一の疑問は

Integer.parseInt() 期待する 正しい の文字列が渡されることを期待します。を渡すと、必ず 悪い文字列 を意味します。 あなたのプログラム が正しくない("ではありません。 あなたのユーザー は馬鹿だ" ではありません)。Integer.parseInt() があるコード片を MUSTセマンティクス 一方では入力が不正確な場合にも対応できるようにする必要があります。 SHOULDセマンティクス .

では、簡単に説明すると、どのように SHOULDセマンティクス を実装する必要があります。 MUST ライブラリ .

どのように解決するのですか?

これはいい質問ですね。もっと多くの人がこのようなことについて考えてくれればと思います。

IMHOでは、ゴミのようなパラメータを渡された場合、チェックされていない例外を投げることは容認されています。

一般的に言えば BadDataException なぜなら、プログラムの流れを制御するためにExceptionを使うべきでないからです。例外は例外のためにあるのです。あなたのメソッドの呼び出し元は の前に そのため、ゴミを渡すことは回避可能であり、したがって プログラミング エラー ということは、チェックされていない例外を投げてもいいということです。

を宣言することについては throws NumberFormatException - という宣言は、NumberFormatExceptionがチェックされていないため、ほとんど気づかないので、それほど有用ではありません。しかし、IDEはこれを利用することができます。 try/catch で正しくラップすることを提案します。良い方法は、javadocも使用することです。

/**
 * Adds two string numbers
 * @param a
 * @param b
 * @return
 * @throws NumberFormatException if either of a or b is not an integer
 */
public static int sum(String a, String b) throws NumberFormatException {
    int x = Integer.parseInt(a); 
    int y = Integer.parseInt(b); 
    return x + y;
}

編集済み :

コメントされた方々のご指摘はもっともです。これがどのように使われるのか、アプリの全体的なデザインを考える必要があります。

もしこのメソッドがあちこちで使われ、すべての呼び出し元が問題に対処することが重要なら、メソッドはチェックされた例外を投げると宣言しますが(呼び出し元に問題に対処することを強いる)、コードを乱雑にするため try/catch をブロックします。

一方、信頼できるデータでこのメソッドを使用する場合は、上記のように宣言します。なぜなら、このメソッドが爆発することはないと予想され、本質的に不要な try/catch ブロックのようなコードの混乱を避けることができます。