【问题标题】:Java generic array from null generic type来自空泛型类型的 Java 泛型数组
【发布时间】:2011-06-13 11:33:21
【问题描述】:

将 Array.newInstance 静态方法视为在 Java 中创建泛型类型数组的一种方式。 我没有看到如何从一个空泛型类型参数创建一个泛型数组:

/**
* Creates and fills a generic array with the given item
*/
public static <T> T[] create(T item, int length)
{
   T[] result = (T[]) Array.newInstance(item.getClass(), length);

   for(int i = 0; i < length; i++)
      result[i] = item;

   return result;
}

当我打电话时,上述方法有效。创建(“ABC”,10);我得到一个长度为 10 的 String[],在数组的所有位置都带有“abc”。 但是我怎样才能让一个空字符串参数返回一个长度为 10 且所有位置都为空的字符串数组呢?

例如

String nullStr = null;
String[] array = create(nullStr, 10); // boom! NullPointerException

有没有办法在不使用其成员之一的情况下获取“项目”类(因为它是空的)?
我知道我可以新建一个数组String[] array = new String[10],但这不是重点。

谢谢

【问题讨论】:

  • 在这种情况下是不可能的——只有剩下的类型信息item一起使用(但如果它为空,则此信息自然不会:-)。这可以通过使用Class 来完成,或者,也许只是create(SomeDefault, 10),例如create("", 10)。仅供参考:C#(不是 Java)有 reified types 并支持 typeof(T) 等等。哦,查看具体类型的链接,其中还谈到了类型擦除:-)

标签: java generics


【解决方案1】:

也许这很有用。

public static <T> T[] create(Class<T> clazz, int length)
{
   T[] result = (T[]) Array.newInstance(clazz, length);
   return result;
}

【讨论】:

  • 如果 clazz = null 仍然会抛出 NullPointerException
  • @pablochan "Naturally" :-) 但不同之处在于给定类型可以访问一个类。传递“清单”只是调用者的责任。
  • @pablochan 当然可以。 String x[] = create(String.class, 10); 不同之处在于调用者知道 T 的类型并且此时不受类型擦除规则的约束。
  • @pst:考虑到 OP 想要做什么,这不是一个很好的例子 (create(null, 10))
  • @pablochan 类型擦除位仍然很重要。虽然更复杂,但可以从类型 String[] 中获取类型 String ——也就是说,信息仍然可用。见download.oracle.com/javase/6/docs/api/java/lang/…
【解决方案2】:

正如你所指出的,你不能打电话:

create(null, 10)

因为您的代码无法确定类型(它最终会调用 null.getClass() => NPE)。

您可以单独通过课程:

public static <T> T[] create(Class<T> type, int length, T fillValue)
{
   T[] result = (T[]) Array.newInstance(type, length);

   for(int i = 0; i < length; i++)
      result[i] = fillValue;

   return result;
}

// Some optional convenience signatures:

public static <T> T[] create(Class<T> type, int length) {
    return create(type, length, null);
}

public static <T> T[] create(T fillValue, int length) {
    if (fillValue == null) {
        throw new IllegalArgumentException("fillValue cannot be null");
    }
    return create(fillValue.getClass(), length, fillValue);
}

public static void main(String[] args) {
    String[] a = create(String.class, 10, null);
}

【讨论】:

    【解决方案3】:

    那么,为什么不将方法改为采用 Class 对象,直接传入String.class? Java 无法获取null 的类类型,因为它没有类类型!任何对象都可以为空。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多