次のような IDL を使用して定義された Avro スキーマがあります。
protocol MyProtocol {
record Gizmo {
string name;
int cost;
int weight;
}
record Gadget {
string name;
int cost;
double width;
double height;
}
record Order {
long id;
array<union{Gizmo, Gadget}> items;
}
}
このスキーマから自動生成された Java クラスを使用しています。アイテム配列に入れることができるのはギズモとガジェットだけではありませんが、すべてに名前とコストがあると規定しましょう。
私の理解では、Avro レコードの継承を指定する方法はないためgetItems()
、Order オブジェクトでは必ずList<Object>
. とはいえ、もう少しコンテキストと型安全性を備えたものが欲しいです。これまでに 3 つのアプローチを思いつきましたが、どれもあまり口に合いそうにありません。
アプローチ 1: への未チェックのキャストを実行しList<SpecificRecord>
(実際には へのキャスト、次にジェネリクスのしくみによりList
への別のキャスト) 、 name と cost がそれぞれフィールド 1 と 2 になることを知って、 を使用します。それらを取得したら、適切な型にもキャストする必要があります。これは信じられないほど壊れやすいようです。List<SpecificRecord>
get(int field)
アプローチ 2:項目配列を反復処理し、各項目を個別にキャストします。最初のアプローチのように、indexed getにキャストしSpecificRecord
て使用するか、一連のinstanceof
チェックを実行してから名前でフィールドを取得することができます。これは壊れやすいか、面倒です。
アプローチ 3:SpecificRecord
適切なクラス階層を実装して持つ独自のクラスを作成します。これはコードを自動生成する利点を失いますが、最も堅牢なオプションのように見えますが、非常に手間がかかります。
これらのうちどれが最高ですか? または、より良いオプションがありますか?