我正在做Cay S.Horstmann的《Java SE 8》一书中的任务(第6章任务21)

使用@SafeVarargs批注编写一个方法,该方法允许您构建泛化类型数组,如下例所示:

List<String>[] result = Arrays.<List<String> > construct (10) ;
// Sets the result in a list of type List<String>[] with a length of 10

我想要的解决方案是这样的

static <T> T[] construct(int size) {
    ArrayList<String> arr = new ArrayList<>();
    for (int i = 0; i < size; i++) arr.add(null);

    return (T[]) arr.toArray();
}

但这是不正确的,因为发生了擦除之后

线程"main"java.lang.ClassCastException中出现异常:类 [Ljava.lang.Object;不能强制转换为类[Ljava.util.List; ([Ljava.lang.Object;和[Ljava.util.List;位于 加载程序‘bootstrap’)位于Main.main(Main.Java:23)

推荐答案

@SafeVarargs确实已经为解决方案提供了一个线索.将该方法设置为varargs方法.由于可变数量的参数也允许零参数,因此此更改允许不变的调用:

public class Example
{
  @SafeVarargs
  static <T> T[] construct(int size, T... template) {
      return Arrays.copyOf(template, size);
  }

  public static void main(String args[])
  {
    List<String>[] result = Example.<List<String>>construct(10);
    System.out.println(result.getClass().getComponentType());
  }
}

请注意,这里不需要显式类型参数.呼叫者可以简化为

List<String>[] result = Example.construct(10);

这意味着当我们在同一个类中或使用imp或t static …时,我们甚至可以省略声明类

List<String>[] result = construct(10);

但是,当调用方向varargs参数提供实参时,它们可能会出现在结果数组中.要强制使用只有null个元素的数组,可以使用

@SafeVarargs
static <T> T[] construct(int size, T... template) {
    return Arrays.copyOf(Arrays.copyOf(template, 0), size);
}

@SafeVarargs
static <T> T[] construct(int size, T... template) {
    T[] array = Arrays.copyOf(template, size);
    Arrays.fill(array, null);
    return array;
}

可以使用以下工具进行测试

List<String>[] result = construct(10, Collections.emptyList());
System.out.println(result.getClass().getComponentType());
System.out.println(Arrays.toString(result));

But note that the creation of generic arrays is not allowed f或 a reason. Consider

List<String>[] result = construct(10);
Object[] array = result;
array[0] = Arrays.asList(42);
List<String> stringList = result[0];

// this situation is called heap pollution

// at an entirely different place in you application, you might do
String s = stringList.get(0);
// without understanding what's going on

Java相关问答推荐

我正在try 对用户输入的整元进行气泡排序(Java)

如何在Docker容器中使用wireock—Webhooks阻止请求?

缩小画布比例后更改滚动窗格的内部大小

使用Spring Boot3.2和虚拟线程的并行服务调用

安装Java Jar应用程序的Install4j遇到ClassNotFoundException的运行时错误

具有阻塞方法的开源库是否应该为执行提供异步选项?

PDFBox未加载内容

如何在Java记录中设置BigDecimal类型属性的精度?

如何让JVM在SIGSEGV崩溃后快速退出?

使用OAuth 2.0资源服务器JWT时的授权(授权)问题

错误:未找到扩展元素在JBossEAP 7.2中安装FUSE时出错

EXCEL中的公式单元格显示#NAME?

从LineChart<;字符串、字符串和gt;中删除数据时出现特殊的ClassCastException;

如何使这两种方法合二为一?

Java在操作多个属性和锁定锁对象时使用同步和易失性

如何在ApacheHttpClient 5中为单个请求设置代理?

Java KeyListener不工作或被添加

在具有Quarkus Panache的PostgreSQL中将JSON数据存储为JSONB时,会将其存储为转义字符串

如何使用Java ZoneID的区域设置?

在Spring Boot中使用咖啡因进行缓存