Extending Generic Classes
Solution 1:
Let's look at this definition:
public class Extend1<T, E> extends MyGeneric<T, E> {}
Here T
and E
are each present twice and in two different roles
- in
Extend1<T,E>
you define type arguments. This means that the typeExtend1
has two (unbounded) type argumentsT
andE
. This tells the Java compiler that those who useExtend1
need to specify the types. - in
extends MyGeneric<T,E>
you use the previously defined type arguments. IfT
andE
were not known to be type arguments here, thenT
andE
would be simple type references, i.e. the compiler would look for classes (or interfaces, ...) namedT
andE
(and most likely not find them).
Yes, type arguments follow the same syntactic rules as any other identifier in Java, so you can use multiple letters ABC
or even names that can be confusing (using a type argument called String
is legal, but highly confusing).
Single-letter type argument names are simply a very common naming strategy.
Solution 2:
I was wondering how Java knows when the types given in the superclass are going to be defined when the subclass is instansiated, and when they are actual class names (i.e. How does it know T, E are not class names)?
Java doesn't care. If you do...
class MyGeneric<String> extends ArrayList<String> {
String value;
}
is it permissible (even if uncommon) to use more than one letter for the generic types? What if (through some sever error of planning) The types conflict with an existing class e.g.
Yes, you can use any valid Java identifier for type parameters.
Names can be in conflict, but Java won't treat this as an error. Identifiers between <
...>
will always be treated as type parameters, regardless if the identifier corresponds to a class name.
It may get quite confusing though. Here's an example:
class MyGeneric<String> extends java.util.ArrayList<String> {
String value;
}
class Test {
public static void main(String... args) throws Exception {
MyGeneric<Integer> obj = new MyGeneric<Integer>();
obj.value = 5;
// ^
// |
// '--- Assign an integer to what seems to be a String!
}
}
Similar question:
- Unboxing issues
Solution 3:
There is no problem with:
public class E{}
public class Foo<E>{}
Because in the context of Foo<E>
, E
is a type.