20

を解析する必要があるこの状況に遭遇しStringましたがint、をどうすればよいかわかりませんNumberFormatException。私がそれを捕まえなくてもコンパイラは文句を言いませんが、私はこの状況を適切に処理していることを確認したいだけです。

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        i = 0;
    }
    return i;
}

このようにコードを単純化したいと思います。コンパイラには問題はありませんが、スレッドはで終了しNumberFormatExceptionます。

private int getCurrentPieceAsInt() {
    int i = 0;
    i = Integer.parseInt(this.getCurrentPiece());
    return i;
}

Google CodeProは、何らかの方法で例外をログに記録することを望んでおり、これがベストプラクティスであることに同意します。

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        i = 0;
        e.printStackTrace();
    }
    return i;
}

0現在のピースが数値でないか、解析できない場合に、このメソッドを返すようにします。明示的にキャッチしないNumberFormatExceptionと、変数が割り当てられませんiか?または、返されるデフォルト値はありInteger.parseInt()ますか?

一般的なスタイルでは、例外をキャッチした場合は、どこかにログを記録する必要があります。ログに記録したくありません。この例外が時々スローされるのは通常の操作ですが、これも私にはうまくいきません。Integer.parseInt()ただし、例外をスローするかどうかを通知する関数が見つかりません。したがって、私の唯一の行動方針は、それを呼び出して例外をキャッチすることであるように思われます。

javadocparseIntあまり役に立ちません。

これが私が知りたい特定の質問です:

  • Integer.parseInt()呼び出す前にをスローするかどうかを教えてくれる、呼び出すことができるメソッドはありNumberFormatExceptionますか?そうすれば、これは決して起こらないはずなので、ログに記録するのに問題はありません。
  • 単に例外をキャッチしない場合、変数は割り当てられませんか?次に、数値ではなく、例外をキャッチしない場合に必要な値に初期化します。
  • どういうわけか、私がそれを気にしないことを明示的に例外にマークする方法はありますか?これはに似たものになると思いますAWTEvent.consume()。もしそうなら、GoogleCodeProがこれを「ログに記録されていない」と見なさないようにこれを行います。
4

8 に答える 8

13
  • Integer.parseInt()が呼び出す前にNumberFormatExceptionをスローするかどうかを教えてくれる、呼び出すことができるメソッドはありますか?そうすれば、これは決して起こらないはずなので、ログに記録するのに問題はありません。

悲しいことに、違います。少なくともコアJavaAPIにはありません。書くのは簡単ですが、以下のコードを変更するだけです。

  • 単に例外をキャッチしない場合、変数は割り当てられませんか?次に、数値ではなく、例外をキャッチしない場合に必要な値に初期化します。

例外をキャッチしない場合、スタックは、それを処理するキャッチブロックに到達するまでアンワインドするか、完全にアンワインドしてスレッドを停止します。実際、変数は割り当てられませんが、これは正確には希望どおりではありません。

  • どういうわけか、私がそれを気にしないことを明示的に例外にマークする方法はありますか?これはAWTEvent.consume()に似たものになると思います。もしそうなら、GoogleCodeProがこれを「ログに記録されていない」と見なさないようにこれを行います。

この特定の警告を無視するようにCodeProに指示する方法があるかもしれません。確かに、FindBugsやCheckstyleなどのツールを使用すると、特定の場所で警告をオフにすることができます。(編集:@Andyはこれを行う方法を指摘しています。)

私はあなたが欲しいものは@davebによって言及されたCommonslangパッケージのようなものだと思います。このような関数を書くのはとても簡単です。

int parseWithDefault(String s, int def) {
    try {
        return Integer.parseInt(s);
    }
    catch (NumberFormatException e) {
        // It's OK to ignore "e" here because returning a default value is the documented behaviour on invalid input.
        return def;
    }
}
于 2010-12-10T15:19:45.517 に答える
10

commons langにはNumberUtils.toInt(String、int)があり、これはまさにあなたが望むことを実行します。

NumberUtils.toInt("123", 42) ==> 123
NumberUtils.toInt("abc", 42) ==> 42
于 2010-12-10T15:07:32.760 に答える
3
* Is there a way to mark the exception somehow explicitly that I don't care about it? I'm thinking this would be something similar to AWTEvent.consume(). If so, then I will do this so that Google CodePro doesn't see this as "unlogged".

はい、1行のコードに対してCodePro監査ルールをローカルで無効にすることができます。

http://code.google.com/javadevtools/codepro/doc/features/audit/locally_disabling_audit_rules.html

とはいえ、すべての例外キャッチブロックに診断ログを含める必要は必ずしもありません。場合によっては、デフォルトのコースを受講するのが最善の方法です。時々それはユーザーと対話することです。場合によります。

于 2010-12-10T15:25:21.300 に答える
1

現在および将来の使用のために独自の便利なメソッドを作成します。

public static int parseInt(final /*@Nullable*/ String s, final int valueIfInvalid) {
    try {
        if (s == null) {
            return valueIfInvalid;
        } else {
            return Integer.parseInt(s);
        }
    } catch (final NumberFormatException ex) {
        return valueIfInvalid;
    }
}

Integer.parseInt()が呼び出す前にNumberFormatExceptionをスローするかどうかを教えてくれる、呼び出すことができるメソッドはありますか?そうすれば、これは決して起こらないはずなので、ログに記録するのに問題はありません。

私が知っていることではありません。存在する場合は、値を2回解析することになります(検証に1回、解析に1回)。例外を回避したいことは理解していますが、この場合、これは例外をキャッチしています。これはJavaの標準イディオムであり、別のイディオムを提供していません(少なくとも私が知っていることです)。

単に例外をキャッチしない場合、変数は割り当てられませんか?次に、数値ではなく、例外をキャッチしない場合に必要な値に初期化します。

例外をキャッチする必要があります(何もしない場合でも)。そうしないと、ブロックをエスケープしてスタックを介してスローされます。

どういうわけか、私がそれを気にしないことを明示的に例外にマークする方法はありますか?これはAWTEvent.consume()に似たものになると思います。もしそうなら、GoogleCodeProがこれを「ログに記録されていない」と見なさないようにこれを行います。

何も知りません。私は上記の便利な方法を使用します(すべてのプロジェクトで使用できる一般的なユーティリティの小さなコレクションに似たようなものがあります)。

あなたが扱っているのが本当に正常な状態であるならば、私はそれを記録しません。私はGoogleCodeProに精通していませんが、警告を抑制する方法があることを願っています。たとえば、ある種の@SuppressWarnings( "xxx")アノテーション/キーワードです。


編集:私は以下のコメントでこれらのコメントを指摘したかった

このアプローチはまだ例外を処理しません。例外をキャッチして何もしないのは悪い形式です。これが私がより良い解決策を探している理由です

...例外(状況)、示されたvalueIfInvalidを返すことによって処理されています。あなたが言及している「悪い形」は、盲目的にそして無意識のうちに空のキャッチブロックを書き、その事件を真に検討して対処するために二度と戻ってこないという悪い習慣を指します。例外シチュエーションが考慮され、そのシチュエーションに対して正しいことを実行する場合(正しいことは何もしないことであっても)、例外を「処理」したことになります

于 2010-12-10T15:08:25.320 に答える
0

あなたがしているようにあなたは例外をキャッチする必要があります。面倒ですが、最善のアプローチです。

文字列が有効なintでない場合に0を返すJavaAPIメソッドはありません。

文字列がintでない場合、例外がスローされるため、実行中に例外をキャッチしない限り、int変数は設定されません。

于 2010-12-10T15:02:50.660 に答える
0

最初のコードブロックは正しいです。i例外が発生したときに暗黙的に0に変換されることはなく、その例外をキャッチする必要があります。i内部で0に設定するのcatchは正しいです。単に。に置き換えることができますi = 0;return 0;。この場合、例外処理を回避することはできません。

明確にするために、これを使用できます。

private int getCurrentPieceAsInt() {
    int i = 0;
    try {
        i = Integer.parseInt(this.getCurrentPiece());
    } catch (NumberFormatException e) {
        // log that an exception occured if it's needed
        return 0;
    }
    return i;
}
于 2010-12-10T15:05:06.170 に答える
0

ゲッターからどのように処理するかが明確でない場合は、それをキャッチして、代わりに呼び出し元に処理させる必要があります。それがどのように扱われるべきかを知っているなら、あなたはただそれをするべきです。この場合、ログに記録する必要がないか、非常に役立つ場合があります。

例外の処理方法がわからず、ログを読む人に例外を任せている場合は、例外のログ記録がより便利です。

于 2010-12-10T15:09:28.173 に答える
0

他の人が述べているように、整数を検証するために呼び出すことができる組み込みのコアJava APIメソッドはありませんが、例外処理を使用せずCharacterにクラスを使用して入力を検証できます。例えば:

package com.example.parseint;

public class ValidateIntExample {
    public static boolean isInteger(String s) {
        if (s == null) {
            return false;
        }

        s = s.trim();

        if (s.length() == 0) {
            return false;
        }

        int start = 0;
        if (s.charAt(0) == '-') { // handle negative numbers
            if (s.length() == 1) {
                return false;
            }
            else {
                start = 1;
            }
        }

        for (int i = start; i < s.length(); i++) {
            if (! Character.isDigit(s.charAt(i))) {
                return false;
            }
        }

        return true;
    }
}

実際、parseIntそれ自体はCharacter.isDigit内部で使用されます。これは、JREソースコードで確認できます。(申し訳ありませんが、parseIntここにメソッドを含めましたが、ライセンス条項で許可されているかどうかはわかりません。)Eclipseを使用していて、プロジェクトにJREソースコードが添付されている場合は、正しく行うことができます-コード内のメソッドInteger.parseIntをクリックし、[宣言を開く]をクリックします。

于 2012-12-12T23:39:26.870 に答える