Java 11+ "generic array creation" 错误(使用 BlueJ)

Java 11+ "generic array creation" error (using BlueJ)

我是 Java 的新手,我正在使用当前版本的 BlueJ 进行编程。当尝试初始化一个包含一周中所有日期的字符串数组时,我收到错误消息 "generic array creation" 我很好奇如何解决这个问题,因为我在网上找到的所有结果都已经过时了日期。该代码适用于还可以跟踪星期几的时钟。我的代码如下:

daysOfWeek = new ArrayList<String>[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

我非常乐意更新此 post 以提供可能需要的任何其他信息以提供帮助。谢谢你的时间。

从 Java13 开始,仍然禁止创建通用数组。原因与数组在运行时知道它们的组件类型这一事实有关,但泛型会受到所谓的 type-erasure 的影响。也就是说,您的问题有以下示例:

daysOfWeek = new ArrayList<String>[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

上面试图创建一个ArrayList<String>[];换句话说,数组列表的数组。这很可能不是您真正想要做的。尽管名称为 ArrayList,但 class 并未直接参与数组的创建 — 该名称仅表示列表由数组 支持 。鉴于您的数据只是一周中每一天的名称,您可能想要的是 String[]List<String>:

// array
String[] daysOfWeek = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

// list
List<String> daysOfWeek = new ArrayList<>(List.of("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"));

请注意,如果您不使用 Java 11+,则可以替换使用 List#of with Arrays#asList(T...)。如果您正在使用 Java 11+,那么请考虑直接使用 List#of 的结果,而不是将结果复制到可修改的 ArrayList 中(假设您不打算修改列表)。

您可能还想考虑使用 java.time.DayOfWeek 枚举而不是 String 来表示一周中的每一天。枚举类型更安全,更不容易出错,并且可以轻松地与您可能使用的任何其他 java.time class 进行交互。

List<DayOfWeek> daysOfWeek = List.of(DayOfWeek.values());

在使用数组之前,您应该始终默认使用 List(或其他一些集合)。如果您绝对必须使用数组,则可以使用以下方法解决 "generic array creation" 错误:

// unbounded T
@SuppressWarnings("unchecked")
T[] array = (T[]) new Object[size];

// or if, for instance, T is upper-bounded by CharSequence
@SuppressWarnings("unchecked")
T[] array = (T[]) new CharSequence[size];

// or if the component type is itself generic
@SuppressWarnings("unchecked")
Comparator<String>[] array = (Comparator<String>[]) new Comparator[size];

然而,以上所有只是一个编译时技巧。每个数组仍将允许存储作为原始组件类型实例的任何对象,而不会在运行时抛出 ArrayStoreException。换句话说,第一个数组仍然接受 Object,第二个数组仍然接受 CharSequence,第三个数组仍然接受 Comparator<?>。这就是为什么对上述每个发出 "unchecked cast" 警告的原因;也就是说,如果不存在 @SuppressWarnings("unchecked") 注释。