简体   繁体   English

创建 Optionals 的多维通用数组

[英]Create a multidimensional generic array of Optionals

I want to create a two-dimensional array (yes I know that this is actually an array of arrays) holding Optionals.我想创建一个包含 Optionals 的二维数组(是的,我知道这实际上是一个数组数组)。 The normal approach for generic array creation does not work though as it fails with a ClassCastException.通用数组创建的正常方法不起作用,因为它因 ClassCastException 而失败。 Here is my code:这是我的代码:

@SuppressWarnings("unchecked")
Optional<Integer>[][] arr = (Optional<Integer>[][]) new Object[5][5];

Is there a way to create such an array, if yes what would be the approach for that?有没有办法创建这样的数组,如果是,那将是什么方法?

In Java " it is illegal to create an array of a generic type, a parameterized type, or a type parameter". 在Java中“ 创建泛型类型,参数化类型或类型参数的数组是非法的”。 "Why is it illegal to create a generic array? Because it isn't typesafe. If it were legal, casts generated by the compiler in an otherwise correct program could fail at runtime with a ClassCastException. This would violate the fundamental guarantee provided by the generic type system. " [Joshua Bloch - Effective Java] “为什么创建泛型数组是非法的?因为它不是类型安全的。如果它是合法的,编译器在正确的程序中生成的强制转换可能在运行时因ClassCastException而失败。这将违反由此提供的基本保证。泛型系统。[Joshua Bloch - Effective Java]

So what solutions are to be able to create multidimensional arrays? 那么什么解决方案能够创建多维数组呢?

The recommended one would be to use a container: 推荐的是使用容器:

List<List<Optional<Integer>>> arr = new ArrayList<>();
for (int i = 0; i < 5; i++) {
    arr.add(new ArrayList<Optional<Integer>>());
}

Generics aside, you can't cast an Object[][] to a raw-typed Optional[][] . 除了泛型,你不能将Object[][]转换为raw-typed Optional[][] You'll get a ClassCastException at runtime. 您将在运行时获得ClassCastException The array has to be created as an Optional[][] , not as Object[][] . 必须将数组创建为Optional[][] ,而不是Object[][] But generics are usually preferred raw types. 但是仿制药通常是首选的原料类型。

It's not that you can never create arrays of generics. 并不是说你永远不能创建泛型数组。 You have to do so indirectly. 你必须间接地这样做。 Typically the way to do it is to create arrays of unbounded-wildcard generics, and then do an unchecked cast -- as you've done -- to the right type: 通常,这样做的方法是创建无界通配符泛型的数组,然后执行未经检查的强制转换(正如您所做的那样)到正确的类型:

@SuppressWarnings("unchecked")
Optional<Integer>[][] arr = (Optional<Integer>[][]) new Optional<?>[5][5];

The above applies to the creation of any arrays of some specific generic type. 以上内容适用于创建某些特定泛型类型的任何数组。 In this case, you might consider using OptionalInt instead of Optional<Integer> . 在这种情况下,您可以考虑使用OptionalInt而不是Optional<Integer> This bypasses any concerns about arrays of generics. 这绕过了对泛型数组的任何担忧。

(Overall I'm somewhat suspicious of the notion of creating arrays or collections of Optionals of any flavor. It just seems like an odd thing to do. There are often better alternatives. But it might be justified in some cases. Anyway, whether an array of Optionals is appropriate for whatever problem you're trying to solve is a separate question.) (总的来说,我有点怀疑创建阵列或任何风格的Optionals集合的概念。这似乎是一件奇怪的事情。通常有更好的选择。但在某些情况下它可能是合理的。无论如何,无论是Optionals数组适用于您尝试解决的任何问题,这是一个单独的问题。)

It is illegal to create an array of generics in Java because of type safety. 由于类型安全,在Java中创建泛型数组是非法的。 Consider using lists instead. 请考虑使用列表。 Link to Oracle manual: https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays 链接到Oracle手册: https//docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM