Java Language Model Structure
I wanted to capture this before I lost the thread.
The relationships among types and elements in the Java language model classes is (to me) extraordinarily complicated, but reasonably precise and useful. So it seems to warrant some exposition.

The notation above is, for the most part, bog-standard UML. Note that these are objects, not classes.
I've chosen arbitrarily to represent TypeMirror instances as ovals and Element instances as rectangles. Stereotypes are mostly informative and certainly not normative.
Types in the Java Language Model are not exactly the types described in the Java Language Specification, which makes things even more complicated, but they are close enough at first glance that for non-edge cases you can kind of think of them as the same thing.
Type Declarations
Loosely, declarations are represented by Elements. Equally loosely, type usages are represented by TypeMirrors and form a sort of substrate "underneath" Elements.
If you start from the orange TypeElement instance (arrayListTE) representing java.util.ArrayList and navigate down, you find its prototypical type (arrayListPT). (Notably, the notion of a "prototypical type" does not seem to appear in the Java Language Specification.) This DeclaredType instance is nameless because all TypeMirrors are (definitionally) nameless. (Names belong to Elements.)
The prototypical type in question has a single type argument, which is a TypeVariable (arrayListETV).
The TypeVariable in question is declared by a TypeParameterElement (arrayListTPE).
(The TypeParameterElement in question is named E because that's how the declaration for java.util.ArrayList is written (the E in public class ArrayList<E>…).)
The TypeParameterElement in question parameterizes the TypeElement declaring java.util.ArrayList, forming a cycle.
Type Usages
On to type usages. java.util.ArrayList, of course, extends java.util.AbstractList.
The ArrayList<E> part of the actual Java declaration does three things:
- Declares the prototypical type (
arrayListPT) represented by the element bearing the namejava.util.ArrayList - Declares a single type parameter (
arrayListTPE) bearing the nameE - Indirectly declares a type variable (
arrayListETV) because the type parameter namedEit just declared declares it as its prototypical type
The extends AbstractList<E>, although it looks somewhat similar, does not do these things, and the E is slightly different. Instead:
- It uses the (declared) type
AbstractList(abstractListTE) - It implicitly "dereferences"
java.util.ArrayList's just-declared sole type parameter element (arrayListTPE) bearing the nameEto yield its prototypical type (a type variable) (arrayListETV) - It passes that type variable as a type argument to the
AbstractListdeclared type (abstractListTU)
Therefore, this usage of the (prototypical)-type-declared-by-the-TypeElement-representing-java.util.AbstractList (abstractListTE) has, as its sole type argument, the prototypical type variable (arrayListETV) of the prototypical type (arrayListPT) declared by the TypeElement representing java.util.ArrayList.
In the model, you get here via the TypeElement#getSuperclass() method.
Note that if you were then to call asElement() on the resulting DeclaredType, the type argument (the type variable from java.util.ArrayList) does not "propagate". You end up with, in other words, the same sort of cyclical structure described above, this time representing java.util.AbstractList and its declarations.
If for some reason you did want to propagate your type usage up the supertype hierarchy, that's what Types#directSupertypes(TypeMirror) is for. (Note that despite its documentation and contract, it does not actually return the direct supertypes described by the Java Language Specification section 4.10 in all cases. Specifically here, to take but one example, the raw type (usage) represented by java.util.AbstractList will not appear as a direct supertype of the declared type (usage) represented by java.util.ArrayList<String>. Other direct supertypes are omitted as well, such as parameterized types whose type arguments are containing wildcards. Somewhat surprisingly, there are a number of fairly major problems with the language model APIs in this general area.)