0

オブジェクトを配列に追加する一般的な(それが正しい用語かどうかはわかりません..)メソッドがあります。

@SuppressWarnings("unchecked")
public static <T>T[] appendArray(T[] a, T b)
{
    T[] temp = (T[])new Object[a.length + 1];
    System.arraycopy(a, 0, temp, 0, a.length);
    temp[a.length] = b;
    return temp;
}

Eclipse では、このコードはエラーも警告も表示しません (抑制された「チェックされていない」警告を除いて)。 .

Integer[] a=new Integer[]{1,2,3};
Integer b=4;
a = appendArray(a, b);

ClassCastExceptionこの場合、投稿したコードの 2 番目のスニペットの 3 行目です。エラーは、[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;なぜそれがこれを行うのかわかりませんし、理解していません.. つまり、ジェネリックを使用しているのに、インスタンス化中Object[]に型にキャストしたもの以外があるのはなぜですか? Tそして、それが行番号 4 (もちろん、コードの 1 ビット目) にある場合、コードの 2 ビット目の 3 行目ではなく、そこで例外がスローされないのはなぜですか?

4

5 に答える 5

3

を使用する代わりに、配列をジェネリック型としてインスタンス化する をSystem.arraycopy使用します。Arrays.copyOf

public static <T> T[] appendArray(T[] a, T b) {
    T[] temp = (T[]) Arrays.copyOf(a, a.length + 1, a.getClass());
    temp[a.length] = b;
    return temp;
}
于 2012-11-28T01:05:58.600 に答える
2

他の回答では、コードを書き直して機能させる方法について説明されていますが、質問の後半はまだ残っているため、次のようになります。

キャストとは何かを根本的に誤解しているようです。実際の型は何も変更しません。これはコンパイラに「ねえ、この型 X の参照が実際には Y であると仮定してください。信じてください。わかっています」と伝えます。

Integer i = (Integer) new Object();

が!Objectになることはありません。Integerコンパイラーに嘘をついたことを JVM が判断すると、実行時にエラーがスローされます。

例で予想よりも遅くエラーが発生する理由は、「T」が Java のコンパイル時のみの概念であるためです。ランタイムの目的で、すべての「T」を に置き換えることができますObject

Integer[]Type Erasure プロセスの一部として、このメソッドが返すという主張が、メソッドが返されて代入を試みようとするポイントに挿入されるかどうかを確認するコード。

于 2012-11-28T01:14:27.877 に答える
2

配列を別の配列にキャストすることはできません。

配列に値型があります。これが[Ljava.lang.Integer;言うことです:整数の配列。そして、それはオブジェクトの配列と互換性のない型です。

すべての Java コレクション クラスが を使用していることに気付きましたObject[]か? その理由は、これがデータを格納できると確信している配列型だからです。

toArrayまた、メソッドがどのように見えるかにも注意してください。取り出したい配列のタイプを知る必要があります。ジェネリックから型を正しく推測することはできません。基本的に、プロトタイプオブジェクトが必要であり、適切な型の配列を作成する必要があります。

于 2012-11-28T01:01:07.660 に答える
1

ジェネリックと配列は混在しません!

それを回避する方法があります。特別なArray.newInstance()メソッドを使用して、特定のコンポーネント タイプの配列オブジェクトを作成できます。

public static <T> T[] appendArray(T[] a, T b) {
    T[] temp = (T[]) Array.newInstance(b.getClass(), a.length + 1);
    System.arraycopy(a, 0, temp, 0, a.length);
    temp[a.length] = b;
    return temp;
}

このコードは、呼び出されたときにエラーをスローしません。

public static void main(String[] args) {
    Integer[] a = new Integer[] { 1, 2, 3 };
    Integer b = 4;
    a = appendArray(a, b);
    System.out.println(Arrays.toString(a));
}

出力:

[1, 2, 3, 4]
于 2012-11-28T01:03:49.117 に答える
0

ArrayListのジェネリック型でジェネリックを作成し、Tそれを配列として取得できます。

@SuppressWarnings("unchecked")
public static <T>T[] appendArray(T[] a, T b)
{
    T[] temp = new ArrayList<T>(Arrays.asList(a)).toArray(a);
    System.arraycopy(a, 0, temp, 0, a.length);
    temp[a.length-1] = b;
    return temp;
}
于 2012-11-28T01:06:34.000 に答える