4

I would like to create a new array with a given type from a class object in GWT.

What I mean is I would like to emulate the functionality of

java.lang.reflect.Array.newInstance(Class<?> componentClass, int size)

The reason I need this to occur is that I have a library which occasionally needs to do the following:

Class<?> cls = array.getClass();
Class<?> cmp = cls.getComponentType();

This works if I pass it an array class normally, but I can't dynamically create a new array from some arbitrary component type.

I am well aware of GWT's lack of reflection; I understand this. However, this seems feasible even given GWT's limited reflection. The reason I believe this is that in the implementation, there exists an inaccessible static method for creating a class object for an array.

Similarly, I understand the array methods to just be type-safe wrappers around JavaScript arrays, and so should be easily hackable, even if JSNI is required.

In reality, the more important thing would be getting the class object, I can work around not being able to make new arrays.

4 Answers 4

4

If you are cool with creating a seed array of the correct type, you can use jsni along with some knowledge of super-super-source to create arrays WITHOUT copying through ArrayList (I avoid java.util overhead like the plague):

public static native <T> T[] newArray(T[] seed, int length)
/*-{
return @com.google.gwt.lang.Array::createFrom([Ljava/lang/Object;I)(seed, length);
}-*/;

Where seed is a zero-length array of the correct type you want, and length is the length you want (although, in production mode, arrays don't really have upper bounds, it makes the [].length field work correctly).

The com.google.gwt.lang package is a set of core utilities used in the compiler for base emulation, and can be found in gwt-dev!com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang.

You can only use these classes through jsni calls, and only in production gwt code (use if GWT.isProdMode()). In general, if you only access the com.google.gwt.lang classes in super-source code, you are guaranteed to never leak references to classes that only exist in compiled javascript.

if (GWT.isProdMode()){
  return newArray(seed, length);
}else{
  return Array.newInstance(seed.getComponentType(), length);
}

Note, you'll probably need to super-source the java.lang.reflect.Array class to avoid gwt compiler error, which suggests you'll want to put your native helper method there. However, I can't help you more than this, as it would overstep the bounds of my work contract.

Sign up to request clarification or add additional context in comments.

Comments

0

The way that I did a similar thing was to pass an empty, 0 length array to the constructor of the object that will want to create the array from.

public class Foo extends Bar<Baz> {

    public Foo()
    {
        super(new Baz[0]);
    }
...
}

Baz:

public abstract class Baz<T>
{
    private T[] emptyArray;

    public Baz(T[] emptyArray)
    {
        this.emptyArray = emptyArray;
    }
...
}

In this case the Bar class can't directly create new T[10], but we can do this:

ArrayList<T> al = new ArrayList<T>();

// add the items you want etc

T[] theArray = al.toArray(emptyArray);

And you get your array in a typesafe way (otherwise in your call super(new Baz[0]); will cause a compiler error).

Comments

0

I had to do something similar, I found it was possible using the Guava library's ObjectArrays class. Instead of the class object it requires a reference to an existing array.

T[] newArray = ObjectArrays.newArray(oldArray, oldArray.length);

Comments

0

For implementing an array concatenation method, I also stepped into the issue of missing Array.newInstance-method.

It's still not implemented, but if you have an existing array you can use

Arrays.copyOf(T[] original, int newLength)

instead.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.