java - 在 Java 中使用可变参数创建泛型数组的潜在风险是什么?

标签 java arrays generics variadic-functions

我找到了一种使用可变参数和匿名内部类创建内联通用数组的方法:

import java.util.Arrays;
import java.util.Objects;

public class GenericArrayCreate<C> {

   public void method() {

      C[] ans = new Object() { C[] c(int length, C ... cs) { return Arrays.copyOf(cs, length); }}.c(10);

      System.out.println(ans.length);
      System.out.println(Objects.toString(ans));

   }

   public static void main(String[] args) {
      new GenericArrayCreate<Class<? extends Integer>>().method();
   }
}

Java 编译器不会对此代码产生任何警告,而代码检查(在 IntelliJ 中)说:

Unchecked generics array creation for varargs parameter

这里发生了什么,为什么要骂人?

最佳答案

在内部你正在创建一个“Object”数组而不是一个“C”数组

试试这段代码:

 public static <C>  C[]  method(int number) {
   return  new Object() { 
     C[] create(int length, C ... cs) {
       return Arrays.copyOf(cs, length); 
     }
   }.create(number);
 }

 public static void main(String[] args) {
   System.out.println(Main.<Integer>method(10));
   System.out.println(new Integer[10]);
 }

[Ljava.lang.Object;@6bc7c054

[Ljava.lang.Integer;@232204a1

如您所见,它们并不相同。

这很危险,因为如果你运行这样的东西:

 public static void main(String[] args) {
   Integer[] integerArray1 = Main.<Integer>method(10);
   Integer[] integerArray2 = new Integer[10];
 }

你将有一个 ClassCastException

[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer

如果你想创建任何类型的数组,你需要发送类来构造数组,你可以这样做:

public static <C>  C[]  method(Class<C> clazz, int number) {
  return  (C[]) Array.newInstance(clazz, number);
}

public static void main(String[] args) {
  Integer[] integerArray1 = Main.<Integer>method(Integer.class, 10);
  Integer[] integerArray2 = new Integer[10];
}

关于java - 在 Java 中使用可变参数创建泛型数组的潜在风险是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37066766/

相关文章:

java - 可扩展 float 操作按钮

java - 使用 ejb2 无状态 session bean 执行顺序事务

c - 字符串值是从另一个字符串获取值

java - 有没有办法从不同的方法访问数组?

javascript - 如何创建输入 id 的数组

java - 泛型的协方差转换

Java JTextfields

java - 在 jFreeChart 中一次显示所有 XYSeries 以提高速度

Java 泛型错误绑定(bind)

c# - 编码 .NET 泛型类型