How does Java's ArrayList work internally?

ArrayList uses an Array of Object to store the data internally.

When you initialize an arraylist, an array of size 10 (default capacity) is created and any element added to the arrayList is actually added to this array. 10 is the default size and it can be passed as a parameter while initializing the arrayList.

When adding a new element, if the array is full, then a new array of double the initial size is created and the last array is copied to this new array, so that now there is empty spaces for the new element to be added.
Since, the underlying data-structure used is an array, it is fairly easy to add a new element to the arrayList as it is added to the end of the list. When an element is to be added anywhere else, say the beginning, then all the elements shall have to move one position to the right to create an empty space at the beginning for the new element to be added.

 This process is time-consuming (linear-time). But the Advantage of ArrayList is that retrieving an element at any position is very fast (constant-time), as underlying it is simply using an array of objects.