If a method is defined as:
<T> List<T> transform(List<T> list)
What does the first T add? As it is essentially the same as:
List<T> transform(List<T> list)
If a method is defined as:
<T> List<T> transform(List<T> list)
What does the first T add? As it is essentially the same as:
List<T> transform(List<T> list)
On
<T> List<T> transform(List<T> list)As it is essentially the same as:
List<T> transform(List<T> list)
It's not.
In the second case, T has to have been defined on the containing class:
class GenericClass<T> {
List<T> transform(List<T> list) { ... }
}
and you can then only pass in/get back a list of the same element type as the class:
GenericClass<String> genericClass = new GenericClass<>();
List<String> stringList = genericClass.transform(Arrays.asList("")); // OK.
List<Integer> intList = genericClass.transform(Arrays.asList(0)); // Error!
However, with the first form, the T isn't defined on the class, so it can be different on each invocation:
class NonGenericClass {
<T> List<T> transform(List<T> list) { ... }
}
NonGenericClass nonGenericClass = new NonGenericClass();
List<String> stringList = nonGenericClass.transform(Arrays.asList("")); // OK.
List<Integer> intList = nonGenericClass.transform(Arrays.asList(0)); // OK.
On
The difference is the scope of T. It can be defined on the class level or for each individual method.
List<T> transform(List<T> list)
This one returns and accepts List<T> where T is the same for all methods.
<T> List<T> transform(List<T> list)
This method has its own T unrelated to the generic type of its class (if any).
On
It is not the same at all.
The <T> declares the variable, the rest is the use of the variable. This straight up fails to compile:
public class Example {
public List<T> transform(List<T> foo) {}
}
try it.
In case this is what you have:
public class Example<T> {
public <T> List<T> transform(List<T> foo) {}
}
Then you have 2 unrelated type variables, both unfortunately named T, which is extremely confusing; I strongly suggest you don't do that (the class has defined a and then the method defines its own T, ensuring that all uses of T in that method declaration are assumed to be the defined on the method; the defined by the class is no longer accessible; it has been 'shadowed'. It is in that sense equivalent to this:
public class Example {
int x;
public void foo(int x) { }
}
The int x of foo is utterly unrelated to the int x; field, but because they have the same name, you have made it impossible to refer to the field named x. At least for this there's an escape (this.x still refers to the field) - no such luxury with generics, so, do not shadow variables like this.
It is somewhat unlikely you want a type var on the method at all if you have this code; but if you really do, don't use T, but use anything else:
public class Foo<T> {
public <Y> List<Y> transform(List<Y> foo) {}
}
On
As was already said, the following are essentially identical.
<T> List<T> transform(List<T> list)
List<T> transform(List<T> list)
But the former also allows one to further constrain T. For example you can do
<T extends Foo> List<T> transform(List<T> list) {
...
}
You can only pass a List<T> if T subclasses Foo.
<T>is the definition. You need to define generic type parameters before you use them, just like you must define variables before you use them.Remember,
Tis just a naming convention. That identifier can be anything. It could be<F>or<Foo>.Suppose they implemented it how you suggest, and the compiler just infers any missing type to be a generic type parameter. Suppose I have a custom class
Foowhich I forgot to import.The compiler would say "Ok, I don't know what Foo is, so let's just assume it's a generic parameter". Your method then compiles just fine, when you would much prefer that the compiler had caught that mistake.
Or maybe you think
Tshould be a special case. You would then be taking something that's currently just a convention and making that a special part of the language. You'd have to deal with the possibility of someone creating a real class calledT.So explicit declarations have their uses, even if they may seem verbose sometimes.