我想从GWT中的类对象创建一个具有给定类型的新数组。
我的意思是我想模仿
的功能java.lang.reflect.Array.newInstance(Class<?> componentClass, int size)
我需要这样做的原因是我有一个偶尔需要执行以下操作的库:
Class<?> cls = array.getClass();
Class<?> cmp = cls.getComponentType();
如果我正常传递一个数组类,这是有效的,但我不能从某个任意组件类型动态创建一个新数组。
我很清楚GWT缺乏反思;我理解这一点。然而,即使GWT的反思有限,这似乎也是可行的。我相信这是因为在implementation中,存在一种无法访问的静态方法,用于为数组创建类对象。
同样,我理解数组方法只是围绕JavaScript数组的类型安全包装器,所以即使需要JSNI也应该很容易破解。
实际上,更重要的是获取类对象,我可以解决不能创建新数组的问题。
答案 0 :(得分:4)
如果您在创建正确类型的种子数组时很酷,可以使用jsni以及超级超级源的一些知识来创建数组而不通过ArrayList进行复制(我避免像瘟疫那样的java.util开销):
public static native <T> T[] newArray(T[] seed, int length)
/*-{
return @com.google.gwt.lang.Array::createFrom([Ljava/lang/Object;I)(seed, length);
}-*/;
其中seed是你想要的正确类型的零长度数组,length是你想要的长度(尽管在生产模式下,数组实际上没有上限,它使[] .length字段工作正确地)。
com.google.gwt.lang包是编译器中用于基本仿真的一组核心实用程序,可以在gwt-dev!com / google / gwt / dev / jjs / intrinsic / com / google中找到/ GWT /郎。
您只能通过jsni调用使用这些类,并且只能在生产gwt代码中使用(如果使用GWT.isProdMode())。通常,如果您只访问超级源代码中的com.google.gwt.lang类,则保证永远不会泄漏对仅存在于已编译的javascript中的类的引用。
if (GWT.isProdMode()){
return newArray(seed, length);
}else{
return Array.newInstance(seed.getComponentType(), length);
}
注意,您可能需要超级源java.lang.reflect.Array类以避免gwt编译器错误,这表明您希望将您的本机帮助程序方法放在那里。但是,我不能帮助你,因为它会超出我的工作合同范围。
答案 1 :(得分:0)
我做类似事情的方法是将一个空的0长度数组传递给想要从中创建数组的对象的构造函数。
public class Foo extends Bar<Baz> {
public Foo()
{
super(new Baz[0]);
}
...
}
巴兹:
public abstract class Baz<T>
{
private T[] emptyArray;
public Baz(T[] emptyArray)
{
this.emptyArray = emptyArray;
}
...
}
在这种情况下,Bar类不能直接创建新的T [10],但我们可以这样做:
ArrayList<T> al = new ArrayList<T>();
// add the items you want etc
T[] theArray = al.toArray(emptyArray);
你以一种类型安全的方式得到你的数组(否则你的调用超级(新的Baz [0]);会导致编译错误。)
答案 2 :(得分:0)
我必须做类似的事情,我发现可以使用Guava库ObjectArrays class。它不需要类对象,而是需要对现有数组的引用。
T[] newArray = ObjectArrays.newArray(oldArray, oldArray.length);