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));
哪里F

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 中的数组是对象,因此有一个类。它们不仅仅是无身份的容器。当你说:

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

您正在创建一个 class 对象String[],并在其中放入两个字符串。有另一种写法可以更清楚地说明:

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

您可以将引用转换为数组,就像您将引用转换为任何其他对象一样;您始终可以进行扩大转换(例如将类型表达式分配给类型String[]变量Object[]),并且可以使用显式强制转换进行缩小转换(例如将类型表达式分配给类型Object[]变量String[])。与其他对象一样,当您执行显式案例时,会在运行时检查对象的实际类,如果它不符合所需的类型,ClassCastException则抛出 a。与其他对象一样,当您进行转换时,对象的实际类不会改变。只有变量的类型

在您的情况下,它看起来像ks.getCertificateChain("ALIAS")返回 a Certificate[]。其中的元素可能是 的实例X509Certificate,但数组本身仍然是Certificate[]. 当您尝试将其强制转换为 时X509Certificate[],将失败。

如果您需要 a X509Certificate[],那么您要做的就是将数组的内容复制到一个新数组中,即 a 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 回答