1.) How does ArrayList then internally represent various Generics Types?
What do you mean "internally"? Generics only exist at compile time. ArrayList has already been compiled by someone else for you and you are just using the class file. So there is no generics there.
Different Java library implementations could write the source differently, but that is of no concern to you. What it does "internally" is an internal implementation detail that a user of the class should not care about.
If you were to write your own class like FixedCapacityStack, then you could do it in different ways:
- You could do the thing where
s is of type Item[] as you have shown above, and you create an Object[] and cast to Item[]
- Or you can make
s of type Object[] and cast to type Item when you get elements out of it
Note that both approaches are the same after erasure, so both will compile to the exact same bytecode. The difference is just style at compile-time.
The advantage of the first approach over the second is that when you get elements out of it, it's already the right type, so you don't have all these ugly casts everywhere. The disadvantage of the first approach is that the initial cast from Object[] to Item[] is basically a "lie", and it will only work if you make absolutely sure not to expose s to the outside of the class (e.g. do not have a method that returns s as type Item[]); otherwise you will have class cast exceptions in unexpected places.
2.) If (assumed) they use the hack mentioned above why it doesn't produce a warning when we compile a program with ArrayList?
There would only be a warning when you actually compile this class. But not if it was already compiled and you are just using the class file. In fact, you don't usually even have the source of ArrayList.
3.) Is there any better way apart from that cast above?
Depends on what you mean by "better". I have shown the two approaches and the advantages and disadvantages of each.