4

私は次の方法を持っています

private ArrayList<User> allUsers = new ArrayList<User>();

public User getUser(int index) {
    try {
        return allUsers.get(index);
    }
    catch(IndexOutOfBoundsException e) {
        // What should I return here?? Say that you want index 0 and no User
        // exists in the ArrayList allUsers, what should I then return? The
        // method needs a User to be returned 
    }
}

ここでの方法がわかりません。簡単に修正できると思いますが、キャッチブロックで何を返す必要がありますか?Eclipseは、をUser返す必要があると不平を言っています。

4

8 に答える 8

15

私の一般的な意見は、処理方法がわからないという例外を決してキャッチしてはならないということです。特にこの場合、IndexOutOfBoundsExceptionはaRuntimeExceptionであり、したがってキャッチする必要がないため、コールスタックに伝播させることもできます。呼び出し元はリストインデックスによってオブジェクトを要求しているので、おそらくどのインデックスを要求するかについてある程度の考えがあります。その場合、スローされたIndexOutOfBoundsExceptionをスローまたは許可することは完全に自然なことのようです。

他の明白なオプションは、例外とを飲み込むことだけですが、適切return nullな戻り値がない場合の呼び出し元側のこのような重大なエラーに対するそのようなアプローチは本当に好きではありません。User特別なインスタンスを返すこともできますが( nullオブジェクトパターンを参照)、それでも、返されたものを確認する責任の呼び出し元を免除することはできません。インターフェイスとUserそのようなチェックの実装に応じて、些細なこともそうでないこともありますが、それでもどこかで行う必要があります。

メソッドが例外をスローする可能性があることを明確にしたい場合は、次のように言ってください。

public User getUser(int index) throws IndexOutOfBoundsException { ... }

または、@ Bela Vizerが提案したように、IllegalArgumentException(RuntimeExceptionでもあります)でラップします。

そして@lcによって指摘されたように、オブジェクトにアクセスする前に、まず自分でオブジェクトが存在するかどうかを確認することをお勧めします。メソッド呼び出しに依存して例外をスローするのではなく、予想されるエラーケースを自分で処理します。ただし、たとえばコレクションがチェックとリターンの間に変更された場合、メソッドがそのような例外をスローする可能性がget()あるという事実については、まだ明確にする必要があります。マルチコアCPU上のマルチスレッドソフトウェアでは、奇妙なことが起こることが知られています。

于 2012-11-17T18:29:39.813 に答える
11

「インデックス0が必要で、ユーザーが存在しない場合は、何を返す必要がありますか?」と自問してください。答えたものは何でも返します。

答えがない場合は、例外を再スローするか、そもそも例外をキャッチしないようにする必要があります。

null存在しないユーザーを要求することが許容できる動作である場合、多くの場合、答えは戻ることであることに注意してください。


補足コメント:通常、例外のキャッチに依存せず、最初にエラー状態をテストすることは「グッドプラクティス」と見なされます。あなたの場合get、最初に無効なオブジェクトインデックスを試し、次にゲッターが爆発した場合に反応します。代わりに、index最初にパラメーターをテストし(少なくともゼロで、の長さよりも短いことを確認してくださいallUsers)、テストに失敗した場合は何かを実行することをお勧めします(nullを返すか、独自の例外をスローします)。

于 2012-11-17T18:28:44.807 に答える
4

多くの可能性があります。それらのいくつかはあなたの信念に依存します。

  • 渡された引数が無効であるため、IllegalArgumentExceptionをスローできます。

  • IndexOutOfBoundsExceptionをスローできます。

  • クライアント(このメソッドの呼び出し元)がそれを処理する必要があることを確認したい場合は、チェックされた例外を宣言することもできます(Exceptionを拡張する例外クラスを定義します)。IllegalArgumentExceptionとIndexOutOfBoundsExceptionは実行時の例外であり、明示的に準備します。

私は通常、インデックスが範囲内にあるかどうかを確認します。そうでない場合はnullを返し、javadocで次の場合はnullを返すことができると述べています...

于 2012-11-17T18:29:16.093 に答える
4

ユーザーが見つからない場合は例外をスローします。この例外は、メソッドが呼び出されたときにキャッチされます。必要に応じて、カスタム例外を使用するようにここでコードを変更できます。何かのようなもの:

public User getUser(int index) throws IndexOutOfBoundsException {
    if(index >= allUsers.size()){
        throw new IndexOutOfBoundsException("User doesn't exist");
    }
    return allUsers.get(index);
}
于 2012-11-17T18:29:53.243 に答える
2

Eclipseを聴かないでください。

2つの選択肢があり、状況に応じて、どちらも良い場合と悪い場合があります。

  1. 戻ることができnullます。
  2. 例外を再スローして(または、まったくキャッチしないで)、呼び出し元のメソッドに処理を依頼することができます。

さらにいくつかのバリエーションがありますが、基本的な選択は上記の2つの間です。問題を適切に処理するか、タスクを呼び出し元に委任します。

そのコードだけから、どれが正しい解決策であるかを判断することは不可能であり、状況により適切なものを知ることができるのはあなただけです。

どちらを選択する場合でも、通常のプログラムの動作0<=index<allUsers.size()をsに依存せずに、手動でインデックスをチェックすることをお勧めします() 。RuntimeException

于 2012-11-17T18:28:53.980 に答える
2

indexユーザー入力であると仮定IndexOutOfBoundsExceptionして、エラーメッセージを表示できるポイントでそれをさらに伝播させてキャッチします。

実際、ルックアップで同じことを実行する前に、最初に検証indexすることができます。allUsers.size()ユーザー入力は、通常、可能な限り早い時点で検証する必要があります。

于 2012-11-17T18:29:00.937 に答える
2

戻りnullますが、そのためにアプリがクラッシュする可能性があると思われる場合は、次のような「nobody」ユーザーを返すことができます。

return new User("nobody", ...);

そして、その場合は関数の外で処理します。

もう1つの方法は、例外をスローして外部で処理することです。

于 2012-11-17T18:30:01.717 に答える
1

いくつかの選択肢があります。

  1. を返しますnull。ユーザーが任意のインデックスを合理的に入力できる場合は、これを実行します
  2. 例外をキャッチしないでください。ユーザーが不正なデータを入力する可能性があることがまったく予期しない場合、つまり、入力がすでにチェックされているために状況を引き起こしたのが「プログラミングエラー」(またはバグ)である場合は、これを実行します。
  3. チェックされた例外をスローします。呼び出し元のコードが問題に対処できる、または対処する必要があると思われる場合は、これを実行してください
于 2012-11-17T18:40:07.480 に答える