2

次のコードがあります

public class Container<T> {
    private T element;
    private T[] tarray;

    public T getElement() {
        return element;
    }

    public void setElement(T element) {
        this.element = element;
    }

    public void add(T element) {
        tarray[0] = element;
    }

    public void CreateArray(int size) {
        //Can this be cleaned up better?
        tarray = (T[]) new Object[size];
    }

    public T get() {
        return tarray[0];
    }

    public Container(T someElement) {
        this.element = someElement;
    }

    public Container() {
    }

    public static void main(String[] args) {
        Container<String> myContaier1 = new Container<String>();
        myContaier1.setElement("Hello");
        myContaier1.CreateArray(1);
        myContaier1.add("GoodBye");
        System.out.println(myContaier1.get());
    }
}

タイプセーフなジェネリック配列を初期化する方法はありませんか?

4

5 に答える 5

6

の特定の値を表すT実際のオブジェクトの形式で具体化されたを提供しない限り、方法はありません。これは、配列型具体化されているのに対し、Generic 型は具体化されていないためです。Class<T>T

于 2013-02-11T20:15:03.277 に答える
1

ここには2つの問題があります。

まず第一に、配列の実際のタイプは常にですObject[]。にキャストしますが、これはに消去するT[]ためにのみ機能します。たとえば、クラス定義が、と言った場合、は失敗します。T[]Object[]<T extends Number>(T[])new Object[]ClassCastException

Class<T>コレクションのコンストラクターに渡してフィールドに保持することで、これを回避できます。

private Class<T> componentClass;
...
tarray = (T[]) Array.newInstance(componentClass, size);

現在、の実際のメモリ内タイプはtarrayですがT[]、チェックされていないキャストエラーが発生します。コンポーネントクラスがありますが、私が知る限りClass.cast()、配列インスタンスのチェックキャストを実行するのに相当するものはありません。

于 2013-02-11T20:27:52.387 に答える
-1

できますprivate T[] tarray;が、 に割り当てることはできません(T[]) new Object[size];。Object の配列を他のクラスの配列と同じにするにはどうすればよいですか。 Tコンパイル後も存在しません。型消去といいます。たとえば、そうする場合

List<Person> persons = new ArrayList<Person>();

List persons = new ArrayList()コンパイル後となります。

于 2013-02-11T20:17:35.773 に答える
-1

JVM でこれを行う方法はありますが、Java でこのようなことを行うには、定型コードを大量に作成する必要があります。Scala では、マニフェストを使用して型消去を回避し、キャストせずにジェネリック配列をインスタンス化できます。

例:

class Container[T : Manifest]() { 
  def createArray(size:Int) = Array.ofDim[T](size) 
}

scala> val f = new Container[String]
f: Container[String] = Container@12f3aa66

scala> f.createArray(5)
res7: Array[String] = Array(null, null, null, null, null)

Scala コードは、Java と同じバイトコード クラス ファイルにコンパイルされます (これは、十分な手順を踏んで独自のマニフェストを作成した場合、Java でも可能であることを意味します)。Scala クラスは Java プロジェクトにインポートできますが、Java からこのようなクラスをインスタンス化するのがどれほど難しいかはわかりません。

より複雑な型の状況を処理できるようになりたいと思うことがよくある場合は、Scala を見てください。気に入るかもしれません。

于 2013-12-19T21:06:01.370 に答える