2

特定の状況下で、Firebase の Java API で驚くべき動作が見られます。java.lang.Long を処理しているときに、java.lang.Integer のインスタンスが返されます。JUnit テスト ケースの例を次に示します。

public class LongsTest extends TestCase {
  public void testSetLong() throws Exception {
    Firebase firebase = new Firebase("http://www.example.com");
    firebase.addChildEventListener(new ChildEventListener() {
      @Override public void onChildRemoved(DataSnapshot s) {}
      @Override public void onChildMoved(DataSnapshot s, String p) {}
      @Override public void onChildChanged(DataSnapshot s, String p) {}
      @Override public void onChildAdded(DataSnapshot s, String p) {
        Map<String, Object> map = s.getValue(new GenericTypeIndicator<Map<String,Object>>() {});
        System.out.println(map.get("key").getClass());
      }
      @Override public void onCancelled() {}
    });
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("key", new Long(15));
    firebase.child("foo").setValue(map);
    Thread.sleep(1000);
  }
}

このコードを実行すると、出力されclass java.lang.Integerます! の本体を次のように変更するため、Firebase は明らかに、コードのどこかに Long があることをまだ認識していますonChildAdded

Map<String,Object> map2 = (Map<String,Object>)s.getValue();
System.out.println(map2.get("key").getClass())

正しく印刷されclass java.lang.Longます。何が起きてる?

4

1 に答える 1

6

Firebase 開発者はこちら。これは実際には非常に微妙な動作であり、Firebase SDK で使用される基盤となる json ライブラリ (Jackson) に関係しています。デフォルトでは、Firebase は int と long の両方を long として内部的に保存します。したがって、データを返すように要求すると、デフォルトで Long が返されます。

ただし、GenericTypeIndicator を使用すると、Firebase のデフォルトの動作がオーバーライドされ、指定された型にマーシャリングしようとすると、Jackson のデフォルトの動作に直接移行します。この場合、Jackson が Integer に収まる数値に遭遇すると、それが実行されます。大きすぎて Integer に収まらない数値が検出されると、Long が返されます。

練習として、変更してみてください

map.put("key", new Long(15));

map.put("key", (long)Integer.MAX_VALUE + 1)

結果のクラスが Long であることがわかるはずです。

これの根拠は、GenericTypeIndicator が Firebase のデフォルトをオーバーライドする方法であるということです。Object を指定する GenericTypeIndicator を使用することで、基になるデシリアライザーに具体的な型の選択を任せることになります。この場合、辞書にすべての Long がある場合は、Map< String, Long > を実行できます。そうでない場合は、遭遇した整数をロングに変換しても安全です。Integer に収まらない値は、すでに Long として返されます。Jackson の詳細については、http ://wiki.fasterxml.com/JacksonDocumentation で (確かに少しまばらな) ドキュメントを見つけることができます。

于 2013-10-10T17:45:17.020 に答える