9

わかりましたので、私は独自の XML シリアライゼーションをセットアップしています (Java に組み込まれているものも含めて、他にもあることは知っていますが、学ぶために自分でやっています。連載を停止しています。私は現在、逆シリアル化 (XML ファイルを読み取り、ファイル内のデータに基づいてオブジェクトを組み立てる) を行っており、ジェネリック型の設定で問題が発生しています。広範な調査の結果、クラスのジェネリック型を取得する方法を見つけたので、シリアライズ時にそれらを記述できましたが、これを行う方法がわかりません。

Class c = Class.forName(string);
ArrayList<c> list = new ArrayList<c>();

C# でこれに対するいくつかの回答を見てきましたが、明らかに C# は Java よりも汎用性が高く、そのソリューションを Java で再現する方法はありません。リフレクションを使用しても、これを行うことはできますか?

4

4 に答える 4

14

できません。

Java のジェネリックは、コンパイル時の構文糖衣にすぎません。Objectこれにより、恐竜が JVM を歩き回っていた昔のようにすべてをキャストする必要がなくなり、コンパイル時の型チェックが可能になります。

追加する編集:実行時に保持されるメタデータがいくつかあり、リフレクションを介してジェネリック クラスを検査できますが、必要なものは何もありません。

于 2013-02-03T08:49:26.063 に答える
1

実行時にジェネリック型を設定することはできません。すべてのジェネリック型情報はコンパイル時に消去されます。

型消去を理解するには、以下の記事を参照してください。

型消去 StackOverflow

型消去チュートリアル

于 2013-02-03T08:51:10.673 に答える
0

いいえ、Genericsはコンパイル時のみであり、コンパイル時の型チェックのみを目的としており、コンパイル時に安全であることが証明できるキャストを回避できます。

考えてみてください。あなたがやりたいことをすることができれば、それは完全に役に立たないでしょう。ArrayList<String>たとえば、要素を取得すると、コンパイラはコンパイル時にその要素が型を持っていると推測できるため、キャストなしでコードStringに型を割り当てることができます。Stringまた、要素を追加しようとすると、コンパイラはコンパイル時にその型がタイプStringであるかどうかを確認できます。そうでない場合は、追加できません。

ただし、コンパイル時に認識されない型パラメーターが必要です。したがって、要素を取得すると、コンパイラはその型について何も認識しないため、型に割り当てることしかできませんObject。そして、何かを入れようとすると、コンパイラは許可するタイプがわからないので、すべてのタイプを許可する必要がありますか?そうすれば、ジェネリックには意味がありません。

したがって、タイプパラメータとして上限タイプを使用する必要があります。好きArrayList<Object> list = new ArrayList<Object>();

于 2013-02-03T20:39:11.607 に答える
0

他に何ができるか(クラスの数が限られている場合)..「インスタンスの」演算子を使用し、配列リストのその場所に応じてオブジェクトのチェックを行います

if(obj instance of abc)
    ArrayList<abc> al = new ArrayList<abc>();

if else または switch をネストできます

于 2013-02-03T08:55:19.743 に答える