I'm trying to implement a linked collection using generics, something like the following.
public class A<E> {
private class B {
private B[] b;
private E item;
private B() {
this.b = new B[2];
}
} // end inner class B
} // end class A
A is the collection and B an element or node in the collection with an array referencing successors/predecessors and an item.
The array creation is not allowed. The error I get is generic array creation
. Am I right to think that what it's actually creating is an array of A<E>.B
?
If not, what's causing the error?
If so, how can I get around this?
I have obviously omitted a substantial amount of code, if what I've provided is not enough please let me know. Any advice would be appreciated. Thank you.
EDIT 1: I should have mentioned that the parameterized type must be the same in A
as in B
. So passing <E>
to the inner class is not possible, as it creates E#2
and leaves A
with E#1
.
You call B
inherits the generic from the outer class, as it is not static. And you can't just make it static, because it will then need E
also.
So your B.b
array will indeed need a type that is generic, i.e. A<E>.B
or if you'd change your code to a static inner class, A.B<E>
(if you would use private static class B<E>
).
In Java, due to the way generics are implemented (by erasure), the type of the array is not well-defined. On one hand, it should be an array of B
, on the other hand, it should be an array of Object
.
The most workable solution seems to be to use Object[]
and cast explicitly.
If you want increased type safety, you can of course use an ArrayList<B>
, which internally uses Object[]
, too!
In you particular code, B b1, b2;
might also be an option which is actually faster (no bounds checking) and needs less memory (no array object; no size information).
B
is a non-static inner class. That means it has a reference to an instance of the enclosing class. So it is implicitly parameterized by the type parameter of outer class. So when you write B
, it means A<E>.B
. To create an array, you should use the raw class. However, B
is not the raw class; to refer to the raw class you need to explicitly qualify it: A.B
So this is that you want:
this.b = new A.B[2];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With