4

配列のダウンキャストがどのように機能するかわかりません。
これが機能する例:

String[] sArray = {"a", "b"};  
Object[] o = sArray;  
f((String[]) o);  

static void f(String[] s){  
  System.out.println("Ok");   
}  

ただし、次の場合:
new F(cert, (X509Certificate[]) ks.getCertificateChain("ALIAS"), key));
where Fis

public F(X509Certificate certificate, X509Certificate[] certificateChain, PrivateKey privateKey) {      
}  

私は得るClassCastException

java.lang.ClassCastException: [Ljava.security.cert.Certificate; [Ljava.security.cert.X509Certificate と互換性がありません。

なんで?

4

2 に答える 2

5

Java の配列はオブジェクトであるため、クラスがあります。それらは単なる ID のないコンテナーではありません。あなたが言う時:

String[] sArray = {"a", "b"};

class のオブジェクトを作成しString[]、それに 2 つの文字列を入れています。それをより明確にする別の書き方があります:

String[] sArray = new String[] {"a", "b"};

他のオブジェクトへの参照をキャストできるのとほぼ同じ方法で、配列への参照をキャストできます。いつでも拡大変換を行うことができ (たとえば、 type の式を typeString[]の変数に代入するObject[])、明示的なキャストを使用して縮小変換を行うことができます (たとえば、 type の式を typeObject[]の変数に代入するString[])。他のオブジェクトと同様に、明示的なケースを実行すると、オブジェクトの実際のクラスが実行時にチェックされ、目的の型に適合しない場合は aClassCastExceptionがスローされます。他のオブジェクトと同様に、キャストしてもオブジェクトの実際のクラスは変わりません。変数の型のみが行います。

ks.getCertificateChain("ALIAS")あなたの場合、 a を返すように見えますCertificate[]。その中の要素が のインスタンスである可能性がありますX509Certificateが、配列自体は依然としてCertificate[]. にキャストしようとするとX509Certificate[]、失敗します。

が必要な場合X509Certificate[]は、配列の内容を新しい配列にコピーする必要があります。これはX509Certificate[]. tbk が示唆するようにそれを行うか、次Arrays.copyOfのように呼び出すことができます。

Certificate[] Certificates = ks.getCertificateChain("ALIAS");
X509Certificate[] x509Certificates = Arrays.copyOf(certificates, certificates.length, X509Certificate[].class);
于 2012-08-31T07:58:36.817 に答える
2

Javaで配列をキャストダウンすることはできませんが、次のようにして回避できます。

Certificate[] certs = ...;
X509Certificate[] x509certs = new X509Certificate[certs.length];
for(int i = 0; i < certs.length; i++) {
  x509certs[i] = (X509Certificate)certs[i];
}

編集:これに代わるものがこの投稿に示されています。ただし、System.arraycopy()実行時に同じように実行される可能性が高いものが含まれます。

于 2012-08-31T07:00:07.030 に答える