9

Railsアプリから書き込まれたJavaからMongoDBインスタンスにアクセスしています。32ビットを超える可能性があるため、Longに格納する必要がある整数値を取得しています。

このコードはコンパイルされます:

this.profile_uid  = (Long)this.profile.get("uid");

ただし、型変換の実行時エラーが発生します。

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long

これはおそらく、フィールドがMongoによって整数として返されるためですが、一部のIDはLongとして返される可能性があり、さまざまな理由で、(別のアプリから)DBに書き込まれるタイプを変更できません。32ビットの場合もあれば64ビットの場合もあります。

Javaアプリはどちらかを処理する必要があり、ある種の切り捨てやオーバーフローの問題に遭遇したくありません。Java側ではLongとして読みたいです。

以下の回避策を試しましたが、実行されているようですが、この方法で切り捨てやオーバーフローの問題から安全かどうかはわかりません。NumberJavaのクラスが何をするのかわかりません。

this.profile_uid  = ((Number)this.profile.get("uid")).longValue();

これは合法ですか?どのような副作用がありますか?別の/より良い方法はありますか?

4

2 に答える 2

7

提案された回避策は正当です。NumberJavaのすべての数値クラスのスーパークラスです。フィールド"uid"が数値形式の場合、this.profile.get("uid"))のサブクラスであるオブジェクトが返されますNumber(したがって、キャスト先Numberは常に機能します)。

のすべての具象サブクラスは、クラス内の抽象メソッドとして定義されているため、メソッドをNumber実装する必要があります。longValue()Number

Integer.longValue()内部のint値をlongに変換します。 Long.longValue()内部のlong値を返すだけです。

于 2012-07-02T05:53:31.790 に答える
1

値がLongの整数であるかどうかを知ることが不可能な場合があります。このクラスは、Long値を簡単に取得できるように作成しました。

public class MongoDbHelper {
    public static Long getLongValue(Document doc, String key, Long defaultVal) {
        Object obj = doc.get(key);
        if (obj == null) {
            return defaultVal;
        } else if (obj instanceof Integer) {
            return ((Integer) obj).longValue();
        } else if (obj instanceof Long) {
            return (Long)obj;
        } else {
            throw new ClassCastException("Could not convert " + obj.getClass() + " to Long");
        }
    }
}
于 2018-05-14T15:45:41.347 に答える