在java中向下转换数组

时间:2012-08-31 06:56:54

标签: java arrays casting

我不确定数组的转发是如何工作的 这个例子有效:

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;

不兼容

为什么呢?

2 个答案:

答案 0 :(得分:4)

Java中的数组是对象,因此有一个类。它们不仅仅是无身份的容器。当你说:

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

您正在创建类String[]的对象,并在其中放入两个字符串。有另一种写作方式可以让它更清晰:

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

您可以使用与向任何其他对象转换引用相同的方式转换对数组的引用;您始终可以进行扩展转换(例如,将类型String[]的表达式分配给类型为Object[]的变量),并且可以使用显式转换进行缩小转换(例如,指定类型{的表达式{1}}到Object[]类型的变量。与其他对象一样,当您执行显式情况时,将在运行时检查对象的实际类,如果它不符合所需类型,则抛出String[]。与其他对象一样,对象的实际在转换时不会更改。只有变量的类型

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

如果您需要X509Certificate[],那么您需要做的是将数组的内容复制到一个X509Certificate[]的新数组中。你可以像tbk建议那样做,或者你可以打电话给Arrays.copyOf,看起来像:

X509Certificate[]

答案 1 :(得分:2)

你不能在java中强制转换数组,但你可以通过执行以下操作来解决它:

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

编辑:显示in this post的替代方案。但是,它涉及System.arraycopy(),在运行时可能会执行相同的操作。