4

GWTのクラスオブジェクトから、指定されたタイプの新しい配列を作成したいと思います。

私が言いたいのは、の機能をエミュレートしたいということです

java.lang.reflect.Array.newInstance(Class<?> componentClass, int size)

これが発生する必要がある理由は、次のことを時々行う必要があるライブラリがあるためです。

Class<?> cls = array.getClass();
Class<?> cmp = cls.getComponentType();

これは、通常は配列クラスを渡すと機能しますが、任意のコンポーネントタイプから新しい配列を動的に作成することはできません。

私はGWTの反省の欠如をよく知っています。これは分かります。ただし、GWTの反射が限られている場合でも、これは実行可能と思われます。これを信じる理由は、実装には、配列のクラスオブジェクトを作成するためのアクセスできない静的メソッドが存在するためです。

同様に、配列メソッドはJavaScript配列のタイプセーフなラッパーであると理解しているため、JSNIが必要な場合でも、簡単にハッキングできるはずです。

実際には、より重要なことはクラスオブジェクトを取得することです。新しい配列を作成できないことを回避できます。

4

3 に答える 3

4

正しいタイプのシード配列を作成することに長けている場合は、スーパースーパーソースの知識とともにjsniを使用して、ArrayListをコピーせずに配列を作成できます(ペストのようなjava.utilオーバーヘッドを回避します)。

public static native <T> T[] newArray(T[] seed, int length)
/*-{
return @com.google.gwt.lang.Array::createFrom([Ljava/lang/Object;I)(seed, length);
}-*/;

seedが必要な正しいタイプの長さゼロの配列であり、lengthが必要な長さである場合(ただし、実動モードでは、配列には実際には上限がないため、[]。lengthフィールドが正しく機能します)。

com.google.gwt.langパッケージは、ベースエミュレーション用のコンパイラで使用されるコアユーティリティのセットであり、gwt-dev!com / google / gwt / dev / jjs / intrinsic / com / google /gwt/にあります。 lang。

これらのクラスは、jsni呼び出しを介して、本番のgwtコードでのみ使用できます(GWT.isProdMode()の場合に使用)。一般に、スーパーソースコードでcom.google.gwt.langクラスにのみアクセスする場合は、コンパイルされたjavascriptにのみ存在するクラスへの参照がリークされないことが保証されます。

if (GWT.isProdMode()){
  return newArray(seed, length);
}else{
  return Array.newInstance(seed.getComponentType(), length);
}

gwtコンパイラエラーを回避するために、おそらくjava.lang.reflect.Arrayクラスをスーパーソース化する必要があることに注意してください。これは、ネイティブヘルパーメソッドをそこに配置することをお勧めします。しかし、それは私の仕事の契約の範囲を超えてしまうので、これ以上あなたを助けることはできません。

于 2012-11-25T12:15:43.090 に答える
0

私が同様のことをした方法は、空の長さ0の配列を、配列を作成するオブジェクトのコンストラクターに渡すことでした。

public class Foo extends Bar<Baz> {

    public Foo()
    {
        super(new Baz[0]);
    }
...
}

バズ:

public abstract class Baz<T>
{
    private T[] emptyArray;

    public Baz(T[] emptyArray)
    {
        this.emptyArray = emptyArray;
    }
...
}

この場合、Barクラスは新しいT [10]を直接作成できませんが、これは可能です。

ArrayList<T> al = new ArrayList<T>();

// add the items you want etc

T[] theArray = al.toArray(emptyArray);

そして、タイプセーフな方法で配列を取得します(そうでない場合は、super(new Baz [0]);を呼び出すと、コンパイラエラーが発生します)。

于 2011-02-11T19:36:38.240 に答える
0

同様のことをしなければなりませんでしたが、GuavaライブラリのObjectArraysクラスを使用してそれが可能であることがわかりました。クラスオブジェクトの代わりに、既存の配列への参照が必要です。

T[] newArray = ObjectArrays.newArray(oldArray, oldArray.length);
于 2014-07-22T10:30:58.387 に答える