web-dev-qa-db-ja.com

オブジェクトの配列を目的のクラスの配列にキャストする

復習のために、誰かがこれが(コンパイル時に)動作しない原因を簡単に説明できますか?

private HashSet data;

...

public DataObject[] getDataObjects( )
{
    return (DataObject[]) data.toArray();
}

...そしてこれが機能する方法を以下に示します:

public DataObject[] getDataObjects( )
{
    return (DataObject[]) data.toArray( new DataObject[ Data.size() ] );
}

これを可能にするキャスティング(またはそれが何であれ)で動作するメカニズムについては、はっきりしていません。

28
Daddy Warbox

toArray()はObjectの配列を作成し、キャストするだけでは_Object[]_を_DataObject[]_にすることができないためです。 toArray(DataObject[])は、DataObjectの配列を作成します。

そして、はい、これはコレクションクラスの欠点であり、GenericsがJavaに組み込まれた方法です。あなたはCollection<E>.toArray()がEの配列を返すことができると期待するでしょうが、そうではありません。

toArray(DataObject[])呼び出しについての興味深いこと: "a"配列を十分に大きくする必要がないので、必要に応じてtoArray(new DataObject[0])で呼び出すことができます。

後で配列の長さを取得するために_.length_を使用する場合は、実際にtoArray(new DateObject[0])のように呼び出す方が適切です。初期の長さが大きく、渡した同じ配列オブジェクトが返された場合、後でNullPointerExceptionsに直面する可能性があります

以前にJavaジェネリックについて質問しましたが、これが指摘されましたFAQこれは非常に役に立ちました: http://www.angelikalanger。 com/GenericsFAQ/JavaGenericsFAQ.html

38
Paul Tomblin

意図したように配列をキャストするときに型の安全性を確保するには(DataObject[] dataArray = (DataObject[]) objectArray;)、JVMは配列内のすべてのオブジェクトを検査する必要があるため、実際には型キャストのような単純な操作ではありません。それが、配列インスタンスを渡さなければならない理由だと私は思います。このインスタンスは、toArray()操作によって満たされます。

3
Henning