10

16進値またはその他の非16進値を想定できる文字列を解析する必要があります

0xff0x31またはA、、、PCなどlabel

このコードを使用して、2つのケースを分割します。

String input = readInput();

try {
    int hex = Integer.decode(input);            
    // use hex ...

} catch (NumberFormatException e) {
   // input is not a hex, continue parsing
}

このコードは「醜い」または読みにくいと見なすことができますか?他の(おそらくもっとエレガントな)解決策はありますか?

編集:(私の場合)間違った入力が存在しないことを明確にしたい:それが16進数であるかどうかを区別する必要があるだけです。完全を期すために、 DCPU-16用の単純なアセンブラを作成しています。

4

7 に答える 7

7

例外処理は、Java プログラミング言語の不可欠な部分 (および設計目標の 1 つ) です...「醜い」と思うという理由だけでそれらを捨てるべきではありません。

とはいえ、シンプルで読みやすい方法で s を処理したい場合は、代わりにクラスNumberFormatExceptionの使用を検討してください。NumberUtils

このtoInt(String str, int defaultValue)メソッドは を に変換Stringint、変換が失敗した場合はデフォルト値を返します。文字列が の場合null、デフォルト値が返されます。

 NumberUtils.toInt(null, 1) = 1
 NumberUtils.toInt("", 1)   = 1
 NumberUtils.toInt("1", 0)  = 1

このメソッドは、以下のソース コードに示すように、例外のキャッチと処理をカプセル化します。その結果、クライアントは単一のメソッド呼び出しを行うだけで済みます。

public static int toInt(String str, int defaultValue) {         
    if(str == null) {
        return defaultValue;
    }
    try {
        return Integer.parseInt(str);
    } catch (NumberFormatException nfe) {
        return defaultValue;
    }
}
于 2012-06-22T20:02:14.460 に答える
2

あなたの質問は、これについて尋ねている今日見た 2 番目の質問です。

いいえ、この例外をキャッチすることは完全に適切です。

また、一般的な「例外」よりも、より明示的な例外 (「NumberFormatException」など)をキャッチする方が確実に優れています。

私見では...

PS: どこに例外を置くか: このレベル、またはそれ以上のレベルでは、別の問題です。

経験則は、「何が起こったのか、どのように回復するのが最善かを知っている最低レベル」です。

または、別の言い方をすれば(以下のリンクから引用):

「メソッドは、適切な方法で例外を処理できる場合にのみ、例外をキャッチする必要があります。」

ここにいくつかの議論があります:

于 2012-06-22T19:15:37.933 に答える
1

いいえ、それは「悪い習慣」ではありません。それは状況によって異なります。

たとえば、Android の場合、ユーザーが文字列「123a」を整数のみを受け入れるテキスト ボックスに入力し、その後解析されると、例外がスローされ、アプリケーションがクラッシュします。この場合、例外をキャッチして、ユーザーにテキストを再入力するように求めることは完全に理にかなっています。

于 2012-06-22T19:18:01.830 に答える
1

あなたの場合、データの形式についていくつかの仮定がない限り、isHexDigitメソッドのようなものを使用することをお勧めします-あなたの説明から、16進数とNumberFormatException. 非 16 進数。

これは、例外条件を処理するために例外を使用する必要があり、データからの期待値が16 進数またはスペースで区切られた 16 進数以外の数字である場合、16 進数以外のトークンに遭遇しても例外は何もないためです。

さらに、例外を使用すると、コードが読みにくくなります。データに関するコメントがないと、散在する非 16 進数が受け入れられ、期待される入力であるという事実が隠されます。

その好みを述べたので、このケースを処理するために例外処理を使用する可能性があります。確かに、そうするコードがたくさんあります。このdecode/parseInt/NumberFormatExceptionの組み合わせには、多くの優れた機能が含まれています。私がやっていることを明確に説明する明示的なコメントがなければ、私はこれを使用しません。

于 2012-06-22T19:44:46.653 に答える
0

文脈にもよりますが、多くの場合、それは悪いことですが、悪い入力がある可能性が非常に高く、設定するデフォルトがある場所である場合は、それをキャッチする必要があります。

于 2012-06-22T19:14:49.570 に答える
0

それはあなたができる最善のことです。メソッドは、何らかの成功/エラー インジケーターを返すか、例外をスローするかのいずれかです。どちらが最も便利かという問題です。ここでは Sun が決定を下したので、議論の必要はありません。

これについて私を悩ませているのは、例外に完全なスタック トレースが含まれるということです! 特定のケースで、これらの文字列を何百万も読んでいる場合、(まったく不要な) パフォーマンスの低下に気付くでしょう。重要な場合は、独自のメソッドを作成することを検討してください (Sun コードをガイドとして使用できます)。その後、例外を使用するかどうかを自分で決定できます。その場合は、例外の静的コピーを手元に置いておき、割り当て時間を節約するために常にそれをスローします。そしてオーバーライドfillInStackTraceして何もせず、例外に意味のないスタックトレースがないようにします。

于 2012-06-22T20:09:25.597 に答える
0

そのNot about how good you code looks、しかしhow good your code works………… Ya offcourse it should be readable, 有名な言葉のように……

どんなバカでもコンピューターが理解できるコードを書くことができますが、人間が理解できるコードを書くのは優れたプログラマーだけです。

そのような種類の例外を用意する必要がある場合には、まったく問題ありません。

When you want to catch multiple exceptions which belong to the same inheritance tree, then create a try block, and multiple catch blocks from more specific to more abstract.

例えば:

`Animal <--- Carnivores <--- Dog`

ここで、DogException 、 CarnivoresException 、 AnimalExceptionがあるとします。

そしたらこうなるに違いない、

try{

           // your code 

     }
      catch(DogException d){}
      catch(CarnivoresException c){}
      catch( AnimalException a){}

上記のキャッチは、より具体的なものからより抽象的なものへとカスケードされているため、例外はまさに原因でキャッチされます。

継承がない場合、catch は任意の順序で指定できます...

于 2012-06-22T19:25:26.000 に答える