Trying to use a generic array in Java, is a disaster waiting to happen. The T[]
field is really an Object[]
at runtime, and trying to do otherwise just hides this fact. It makes you think you're dealing with a T[]
, but it's a lie; you're really dealing with an Object[]
. There are very good reasons not to use generic arrays. I'll add that if you peek into the current Oracle implementation of ArrayList
or CopyOnWriteArrayList
, you won't see a generic array being used, but Object[]
explicitly. It makes it clear to the developers and to the readers that the array being handled does not have a generic type.
In your particular case, there are no unsafe operations done with it, so that's good. But be careful if you add a toArray()
method in the future... Just take a look to see how easy it is to make a mistake: add the method
public T[] toArray() {
return queue; // or queue.clone();
}
Looks fine. Even compiles without warnings. Now do:
Queue<String> queue = new Queue<>();
queue.push("foo");
String[] array = queue.toArray();
Looks also fine. Still no warnings. But this will fail at run-time:
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
Runtime is the worst moment to have those exceptions. It is always better to detect bugs as early as possible, and fail directly at compile-time. And this exception, is because the array really isn't a String[]
, but an Object[]
. There are ways around that of course (the simpler being to return Object[]
from the method), but the point is that you're opening yourself to a lot of unforeseen troubles. All in all, if you really want a backing array, don't lie to yourself and:
- Just use
Object[]
. You'll have to cast when pop
ing or push
ing elements, but you can ensure that it is safe to do by having the proper generic type for the methods, just like you have in the current code.
- If you want strong typing, pass the class of the elements as constructor to the
Queue
.
Couple of side-notes:
- It would be preferable to throw an
NoSuchElementException
if the queue is empty inside peek
, instead of failing with an out of bounds exception.
- To copy arrays, you can use
System.arraycopy
, like mentioned in this other answer.