I am not sure how downcasting of arrays works.
Example this works:
String[] sArray = {"a", "b"};
Object[] o = sArray;
f((String[]) o);
static void f(String[] s){
System.out.println("Ok");
}
But for the following:
new F(cert, (X509Certificate[]) ks.getCertificateChain("ALIAS"), key));
where F is
public F(X509Certificate certificate, X509Certificate[] certificateChain, PrivateKey privateKey) {
}
I get ClassCastException
java.lang.ClassCastException: [Ljava.security.cert.Certificate;
incompatible with [Ljava.security.cert.X509Certificate;
Why?
Arrays in Java are objects, and as such, have a class. They aren’t simply identityless containers. When you say:
You are creating an object of class
String[], and putting two strings in it. There is an alternative way of writing it which makes that clearer:You can cast references to arrays in much the same way as you can cast references to any other objects; you can always make a widening conversion (eg assigning an expression of type
String[]to a variable of typeObject[]), and you can make a narrowing conversion using an explicit cast (eg assigning an expression of typeObject[]to a variable of typeString[]). As with other objects, when you do an explicit case, the actual class of the object is checked at runtime, and if it doesn’t fit the desired type, aClassCastExceptionis thrown. As with other objects, the actual class of the object does not change when you cast. Only the type of the variable does.In your case, it looks like
ks.getCertificateChain("ALIAS")returns aCertificate[]. It’s possible that the elements in it are instances ofX509Certificate, but the array itself is still aCertificate[]. When you try to cast it toX509Certificate[], that fails.If you need a
X509Certificate[], then what you will have to do is copy the contents of the array into a new array which is aX509Certificate[]. You can do that as tbk suggests, or you can callArrays.copyOf, looking something like: