Reputation:
I want to create a two-dimensional array (yes I know that this is actually an array of arrays) holding Optionals. The normal approach for generic array creation does not work though as it fails with a 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?
Upvotes: 1
Views: 1310
Reputation: 132370
Generics aside, you can't cast an Object[][]
to a raw-typed Optional[][]
. You'll get a ClassCastException
at runtime. The array has to be created as an Optional[][]
, not as 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>
. 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.)
Upvotes: 0
Reputation: 16775
In Java "it is illegal to create an array of a generic type, a parameterized type, or a type parameter". "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]
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>>());
}
Upvotes: 1