I'm just learning about generics in Java from a textbook, where it talks about a class GenericStack<E>
implemented with an ArrayList<E>
.
Since in order to create a stack of strings, you use
GenericStack<String> = new GenericStack<String>()
or
GenericStack<String> new GenericStack<>()
therefore shouldn't the constructor of
GenericStack
be defined as public GenericStack<E>()
, or public GenericStack<>()
? The answer is no. It should be defined as public GenericStack()
.
Why is this? Obviously the constructor can easily infer the type from the class declaration, but given the verbosity of Java, I'm a bit befuddled why the <E>
or simply the <>
formalism is completely gotten rid of here.
You are confusing a method's declaration with its call site (that is, where you use it). If you want to use a generic that's declared on the class, only ever need to provide the
<E>
or<>
at the call site — not the declaration. And in that regard, a constructor is declared like any other method:Redeclaring the generic (as in the
put
case above) actually shadows it; theE
input(E)
is actually a differentE
than inGenericStack<E>
, despite having the same name. This is confusing, and you should avoid doing it.There are two parts to this:
The generic type parameter given for the class definition is available within the class itself.
You can have generic types specific to individual methods (including constructor).
Look at the following example:
Where as the type
E
is available to the whole of the class, the typeT
is valid only within the constructor.Both the class and the constructor can be generic on their own, i.e. each has its own type parameters. For example
To invoke the constructor with all explicit type arguments
Think of it like this,
A<Integer>
is the concrete class, and<String>A
is the concrete constructor.Because of type inference, we can omit the type argument for the constructor
The type argument for the class can also be omitted and inferred, by "diamond" (
<>
) syntaxI wrote a (long) post on this subject - https://stackoverflow.com/a/32292707/2158288