Cup of Java Cup of Java - 2 months ago 4
Java Question

Cannot cast array of Object to array of another interface

I cannot figure out why I keep getting a

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcs445.a1.ProfileInterface;
error

Here is all of the relevant code that keeps giving me the error

Client

public static void show() {
ProfileInterface p = pick();
if (p == null) return;
System.out.println(p.getName());
System.out.println("About: " + p.getAbout());
System.out.println("Following:");

//error happens at this line below
ProfileInterface[] following = p.following(4);

for (ProfileInterface p2 : following) {
System.out.println(p2.getName());
}
}


Profile class that contains
following
method and extends ProfileInterface

private Set<ProfileInterface> friends = new Set<ProfileInterface>();

public ProfileInterface[] following(int howMany){
if(howMany >= friends.getCurrentSize()){

//And points to this line as the Object Cast Error
return (ProfileInterface[])friends.toArray();

}else{
return (ProfileInterface[])Arrays.copyOf(friends.toArray(), howMany);
}
}


And the Set Class that contains the
toArray
Method

@Override
public T[] toArray() {
T[] returnArray = (T[])new Object[size];
System.out.println("Size of current array is " +size);
for(int i = 0; i < size;i++){
returnArray[i] = setArray[i];
}

return returnArray;
}


I am casting the return array to a
ProfileInterface[]
but it keeps giving me the error

Answer

In light of the fact that Andy Turner's answer will not suit your needs, it seems to me that you have the following options:

  1. Leave the implementation of Set as it is, implement your following() method without invoking toArray(), and hope that nobody else will invoke toArray(), because if they do, it will blow up.

  2. Go to whoever gave you the assignment and protest that the guidelines of the assignment as given cannot receive a reasonable solution, because whoever designed that Set interface obviously never implemented it, or never attempted to invoke the toArray() method of their implementation. If they did, they would have encountered the same error as you did.

  3. Modify the constructor of your class implementing Set to accept the class of the elements, (so technically, you would not be altering the interface of Set,) so it would be invoked as follows:

Set<ProfileInterface> following = new Set<>( ProfileInterface.class );

then, use the following method to create an array from within toArray():

public static <T> T newArray( Class<T> arrayType, int size )
{
    assert arrayType.isArray();
    @SuppressWarnings( "unchecked" )
    T array = (T)Array.newInstance( arrayType.getComponentType(), size );
    return array;
}

(you might want to play with it a bit to suit your needs, for example you might want to have it return T[] instead of T.)

Unless, of course, the Set interface you are trying to implement is java.util.Set, in which case it does already have a toArray( T[] ) method which you can override instead of T[] toArray().

Comments