[ https://issues.apache.org/jira/browse/COLLECTIONS-747?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17034241#comment-17034241 ]
Walter Laan edited comment on COLLECTIONS-747 at 2/11/20 8:34 AM: ------------------------------------------------------------------ No, you will need the actual array Class to make a copy. See java.util.ArrayList#toArray() which return Object[] and toArray(T[]) which creates a copy. Or you could use the class from a key value, but that won't work if all of them are null, which is not forbidden as far as I checked. For example, if want to keep the minimum of two keys, you have to do: {code:java} @SafeVarargs public MultiKey(K key1, K key2, K... keys) { int length = keys.length + 2; @SuppressWarnings("unchecked") // cast is correct because K[].getClass() is passed K[] tmpKeys = (K[]) Arrays.copyOf(keys, keys.length + 2, keys.getClass()); for(int i = length - 1; i > 1; i--) { tmpKeys[i] = tmpKeys[i - 2]; } tmpKeys[0] = key1; tmpKeys[1] = key2; this.keys = tmpKeys; } // which then allows null keys, though need to specify type instead of just diamond (<>) MultiKeyClassCastException[] keys = new MultiKey<>(key1, key2).getKeys(); MultiKeyClassCastException[] keys2 = new MultiKey<>(key1, key2, key3).getKeys(); MultiKeyClassCastException[] keys3 = new MultiKey<MultiKeyClassCastException>(null, null).getKeys(); {code} [https://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java] [https://softwareengineering.stackexchange.com/a/331109] was (Author: wlaan): No, you will need the actual array Class to make a copy. See java.util.ArrayList#toArray() which return Object[] and toArray(T[]) which creates a copy. Or you could use the class from a key value, but that won't work if all of them are null, which is not forbidden as far as I checked. For example, if want to keep the minimum of two keys, you have to do: {code:java} @SafeVarargs public MultiKey(K key1, K key2, K... keys) { int length = keys.length + 2; @SuppressWarnings("unchecked") // cast is correct because K[].getClass() is passed K[] tmpKeys = (K[]) Arrays.copyOf(keys, keys.length + 2, keys.getClass()); for(int i = length - 1; i > 1; i--) { tmpKeys[i] = tmpKeys[i - 2]; } tmpKeys[0] = key1; tmpKeys[1] = key2; this.keys = tmpKeys; } // which then allows null keys, though need to specify type instead of just diamond (<>) MultiKeyClassCastException[] keys = new MultiKey<>(key1, key2).getKeys(); MultiKeyClassCastException[] keys2 = new MultiKey<>(key1, key2, key3).getKeys(); MultiKeyClassCastException[] keys3 = new MultiKey<MultiKeyClassCastException>(null, null).getKeys(); {code} [https://stackoverflow.com/questions/529085/how-to-create-a-generic-array-in-java] [https://softwareengineering.stackexchange.com/a/331109] > MultiKey.getKeys class cast exception > ------------------------------------- > > Key: COLLECTIONS-747 > URL: https://issues.apache.org/jira/browse/COLLECTIONS-747 > Project: Commons Collections > Issue Type: Bug > Components: KeyValue > Affects Versions: 4.4 > Reporter: Walter Laan > Priority: Major > > When using an non-array constructor of MultiKey, an Object[] is created, > which cannot be cast to a K[] > {code} > import org.apache.commons.collections4.keyvalue.MultiKey; > public class MultiKeyClassCastException { > public static void main(String[] args) { > MultiKeyClassCastException key1 = new MultiKeyClassCastException(); > MultiKeyClassCastException key2 = new MultiKeyClassCastException(); > MultiKeyClassCastException[] keys = new MultiKey<>(key1, > key2).getKeys(); > } > } > // running gives (same error if in module): > Exception in thread "main" java.lang.ClassCastException: class > [Ljava.lang.Object; cannot be cast to class [LMultiKeyClassCastException; > ([Ljava.lang.Object; is in module java.base of loader 'bootstrap'; > [LMultiKeyClassCastException; is in unnamed module of loader 'app') > at MultiKeyClassCastException.main(MultiKeyClassCastException.java:8) > {code} > AFAIK, the only way to fix this (with source compatibility), is to only have > a varargs constructors. but I think this breaks binary compatibility though > and cannot be used with the existing constructors. > {code} > @SafeVarargs > public MultiKey(K... keys) { > this.keys = keys; > } > {code} > Workaround is to use array constructor with correct typed array or > {code}Object[] keys = multiKey.getKeys();{code} explicitly. -- This message was sent by Atlassian Jira (v8.3.4#803005)