What is the difference between:
public <T> void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
and
public void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
I read that the method signature for using types should have <T>
before the return type but how come I am still able to create the method without the <T>
? What is the implication if I do or do not put it?
In the second method, the type parameter would be typically defined in the class declaration to which the method belongs:
class MyClass<T> {
public void createArray(T sample){
ArrayList<T> list = new ArrayList<T>();
list.add(sample);
}
...
}
So the second method belongs to a generic type. The first method is a generic method because it defines its own type parameter.
In the first case, the generic parameter T
is defined for the method. Other methods may have a different T
.
In the second case, the generic parameter T
is defined for the class or interface. All methods within that class or interface must have the same T
.
Defining a class-wide generic allows you to enforce the same type parameter on many methods. You can also have fields of the generic type. See ArrayList<t>
for an example.
From the second example, I am guessing this method is defined in a generic class something like this:
class SomeClass<T> {
public void createArray(T sample){ ... }
}
The difference between the first and second example is that in the first example, the T
is effectively a "local" type variable. You could give it a different name, eg S
, to make it a little bit clearer:
class SomeClass<T> {
public <S> void createArray(S sample){ ... }
}
So, S
and T
are both type variables, but are unrelated. T
is defined at class scope, and so can be used to refer to the same type amongst all methods in the class; S
is defined only at method scope.
By using the name T
instead of S
, you are hiding the class-level type variable, T
. This means that, for example, the following would not work:
class SomeClass<T> {
public T getWotsit() { ... }
public <T> void createArray(T sample){
T wotsit = getWotsit();
}
}
because the T
in the signature of getWotsit
and the T
in the variable declaration T wotsit
potentially refer to different types; this is more clear if you use the name S
to write the equivalent code:
class SomeClass<T> {
public T getWotsit() { ... }
public <S> void createArray(S sample){
S wotsit = getWotsit();
}
}
As far as I'm aware, there is no way to refer to the class-level type variable if you've defined a method-level type variable with the same name.
However, both of the following would be fine:
class SomeClass<T> {
public T getWotsit() { ... }
// No additional type variable, so T is the class-level type variable.
public void createArray(T sample){
T wotsit = getWotsit();
}
}
class SomeClass<T> {
public T getWotsit() { ... }
// Type variable has different name, so `T` is the class-level
// type variable.
public <S> void createArray(T sample){
T wotsit = getWotsit();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.