53

このスニペットはNullPointerException、プリミティブ型にボックス化されておらず、呼び出されているという事実のためにスローしLong.longValue()ますよね?

次のようなスニペットがあれば、さらに簡単に確認できます。

long value = (Long) null;

しかし、次のNullPointerExceptionようなより複雑な状況では、これを取得するのはさらに困難です。

long propertyValue = (Long) obj.getProperty(propertyModel.getName());

Javaコンパイラがこれからより快適な例外を作成する可能性はありませんか? 「null オブジェクトをプリミティブ型にキャストしようとしていますが、これはできません!」のIllegalArgumentExceptionようなメッセージが表示されることをお勧めします。

これはより適切ではないでしょうか?どう思いますか?これは実行時にも可能ですか? このキャストを決定できますか?Java バイトコードはまだ見ていません。ソリューションで使用できる可能性があります。

この質問に答えることができます: この動作を実現できるかどうか知りたいです!

4

4 に答える 4

94

Java 言語仕様によると、ボックス化解除はNumber.longValue()、などを呼び出すことでNumber.intValue()行われます。特別なバイト コード マジックは発生していません。これらのメソッドを手動で呼び出した場合とまったく同じです。したがって、これNullPointerExceptionはボックス化解除の自然な結果ですnull(実際、JLS によって義務付けられています)。

別の例外をスローするには、ボックス化解除の変換ごとにnull 2 回チェックする必要があります (1 回は特別な例外をスローするかどうかを決定するため、もう 1 回はメソッドが実際に呼び出されたときに暗黙的に)。言語設計者は、それを正当化するのに十分有用だとは考えていなかったと思います。

于 2010-03-04T19:37:42.920 に答える
1

という意味ではありませんIllegalArgumentException。コンパイラは、値がnull実行時まであるという保証はありません。それが知っているのはタイプだけです。あなたの例ではString.

確かに、実行時に例外がスローされると、コンパイラは問題がnull値であることを認識します。デバッガーを使用している場合は、これを自分で確認できます。したがって、技術的な観点からすると、これがあなたの質問に対する簡単な回答です。はい、それをエラーの説明に含めるコンパイラを作成することは可能です。しかし、価値観に関する特別なメッセージが必要な場合はnull、次に何をすればよいでしょうか? 10 を超える許容範囲外の整数に対する特別なメッセージはありますか? 確かにこれはばかげた例ですが、説明になれば幸いです。

于 2010-03-04T19:33:24.707 に答える
1

このような場合には、小さなプライベート ヘルパーを作成することをお勧めします。これらは、正しいキャスト、エラー メッセージ、およびデフォルト値の生成を処理できます。

操作の十分な「状態」を例外に入れることをお勧めします (この場合、オプション名と値 - 見つからない場合はオプション マップの文字列表現でさえあります)。

何かのようなもの:

private long safeGetLong(Map<String, Option> options, String name) {
  if (name == null || options == null)
    throw new IllegalArgumentExcption("You need to give options and name. (name="+name+", opts=" + options));
  Object val = options.get(name);
  if (val == null)
    throw new ConfigurationException("The option name="+name+" is unknown");
  if (val instanceof Long)
    return val.longValue();

  String strVal = null;
  try
  {
    strVal = val.toString();
    return Long.parseValue(strVal);
  } catch (Exception ex) {
    throw new ConfigurationException("Cannot parse " + name + "=" + strVal + " into a Long.");
  }
}

もちろん、型付きアクセスを許可する構成オブジェクトを持つことはさらに優れています。

それを行うことができる検証フレームワークがいくつかありますが、問題のアプリケーションのIN8Lおよび例外階層またはロギング規則により適しているため、通常、コードを自分で作成することになります。それをジェネリックにするのは難しい。

于 2013-10-15T21:51:37.083 に答える