Fabien Dupuit wrote:From the context, it will find out that <T> parameter from the class is a String so 'a' is therefor a String.
That context is outside the class, in your example. How far away should the compiler look for context like this? Like, in the same file, in the same package, in the same project, on the same computer, in the whole organization you're sharing your computer with? What if there's code somewhere that uses T as a String, and somewhere else there's code that uses T as an Integer? Or a StringBuffer? How can the compiler know, within the class A, what other code is going to use it for?
In general, we want to be able to compile a class based on declarations in that class, not by having to scan code outside the class. Of course when we use another specific class within our class, that other class needs to be compiled before our class. But with generics like T, there's no other class to go and compile first. Instead, your class A needs to have all the info it needs to be compiled, within the definition of T. Code lying around elsewhere is not relevant for compiling class A. Within the class A, the generic parameter T could be anything, since it's just declared there as <T>, with no other restrictions (no super or extends).
Furthermore, the compiler is never going to let you create an instance using "new" without specifying exactly what the class is. That's how the rules work. You can't just say "create some sort of T" and let the computer surprise you - T could mean many things. And with generics, they are generally used in places you need to be flexible, where more than one type is possible. So the rule is, you can't create a new something with a generic type. That is, you can create something like new ArrayList<T> (which is fundamentally an ArrayList), but not a new T.