Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java inheritor array construction and covariant return

(Title sounds a bit too fancy but I couldn't find a match so we'll hope it's descriptive.)

I have a working piece of code as follows:

@SuppressWarnings("unchecked")
public static Copyable[] copyOf(Copyable[] objects, Class type) {
    Copyable[] copies = Arrays.copyOf(objects, objects.length, type);
    for( int i=0; i < copies.length; ++i ) {
        if( objects[i] == null )
            throw new IllegalArgumentException("Copyable[] contains null reference", new NullPointerException());
        copies[i] = objects[i].copy();
    }

    return copies;
}

Not as pretty as I would like, since I have to pass in the array class, but it works for what I want it to do: allocate a new array of a Copyable implementor and fill it using the implemented method.

The problem I'm having is that this gets compiled by GWT, whose JRE Emulation library barfs on correct Java that it hasn't implemented. I need to do this without calling Arrays.copyOf(), and hopefully without reflection.

Note: I'm working on a clone() version but don't really want to rely on clone() either. I feel like there must be a cleaner solution.

like image 949
orbfish Avatar asked Dec 21 '25 01:12

orbfish


2 Answers

How about this:

public static Copyable[] copyOf(Copyable[] objects) {
    Copyable[] copies = new Copyable[objects.length];
    for( int i=0; i < copies.length; ++i ) {
        if( objects[i] == null )
            throw new IllegalArgumentException("Copyable[] contains null reference", new NullPointerException());
        copies[i] = objects[i].copy();
    }
    return copies;
}

There's no need to actually copy the objects array into copies before making copies of the elements themselves.

EDIT

If your Copyable objects are serializable, you can just serialize and then deserialize the array to create a copy. There's a utility function DeepCopy.java in gwt-test-utils that may do exactly what you need.

like image 151
Ted Hopp Avatar answered Dec 23 '25 14:12

Ted Hopp


Why can't you just do: Copyable[] copies = new Copyable[objects.length]; ? That line allocates the array and then you're already filling it with the for loop you included.

like image 45
Chris Avatar answered Dec 23 '25 13:12

Chris



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!