【问题标题】:Creating New Array with Class Object in GWT在 GWT 中使用类对象创建新数组
【发布时间】:2011-02-11 18:33:14
【问题描述】:

我想从 GWT 中的类对象创建一个具有给定类型的新数组。

我的意思是我想模仿

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

我需要这样做的原因是我有一个库,它偶尔需要执行以下操作:

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

如果我正常传递一个数组类,这可以工作,但我不能从某个任意组件类型动态创建一个新数组。

我很清楚 GWT 缺乏反思;我明白这一点。然而,即使考虑到 GWT 的有限反射,这似乎也是可行的。我相信这是因为在implementation 中,存在一个无法访问的静态方法来为数组创建类对象。

同样,我理解数组方法只是 JavaScript 数组的类型安全包装器,因此应该很容易破解,即使需要 JSNI。

实际上,更重要的是获取类对象,我可以解决无法创建新数组的问题。

【问题讨论】:

    标签: arrays gwt jsni


    【解决方案1】:

    如果你很擅长创建正确类型的种子数组,你可以使用 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);
    }-*/;
    

    其中种子是您想要的正确类型的零长度数组,长度是您想要的长度(尽管在生产模式下,数组实际上没有上限,它使 [].length 字段起作用正确)。

    com.google.gwt.lang 包是编译器中用于基本仿真的一组核心实用程序,可在 gwt-dev!com/google/gwt/dev/jjs/intrinsic/com/google 中找到/gwt/lang.

    您只能通过 jsni 调用使用这些类,并且只能在生产 gwt 代码中使用(使用 if 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 编译器错误,这表明您需要将本机辅助方法放在那里。但是,我只能帮助您,因为它会超出我的工作合同的范围。

    【讨论】:

      【解决方案2】:

      我做类似事情的方式是将一个空的、长度为 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);
      

      并且您以类型安全的方式获取数组(否则在您的调用 super(new Baz[0]); 中会导致编译器错误)。

      【讨论】:

        【解决方案3】:

        我不得不做类似的事情,我发现使用 Guava 库的 ObjectArrays class 是可能的。它需要对现有数组的引用,而不是类对象。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-06-09
          • 1970-01-01
          • 2012-07-10
          • 1970-01-01
          • 1970-01-01
          • 2020-02-04
          • 2016-04-20
          • 2013-12-12
          相关资源
          最近更新 更多