The first part of this answer will cover the output part of the type of your question.
The only place where the type is automatically inferred in your example is to call genericMethod .
Definition genericMethod declares two typical types: an unbound BT and T which should be a subclass of BT .
Type T will be inferred in accordance with the rules specified in the Java Language Specification Section 18.2.4 :
The form constraint formula , where S and T are types, is reduced as follows:
...
Otherwise, if T is an output variable, α and S is not a primitive type, the restriction reduces to the estimate S = α.
In your example, you provide an object of type String as an argument of type T According to the above rule, T will be considered equal to String .
Now that T fixed, the output will continue using BT . This type is deduced as follows, section 18.3.1 , which states that an expression of type:
T extends BT, T == String
means
String extends BT
This relationship allows the compiler to bind BT to String , so you get the following implied call:
genericMethod<String,String>("text")
Hope this makes it a little easier.
To answer the second part of your question:
and although T extends BT, these are different types, and GenericClass may have internal logic where the exact type name plays an important role (for example, used as a string key on some map, etc.) .
Without additional restrictions, the compiler will treat T as the equivalent of BT and allow you to call only methods defined as part of the BT type.
Unless you are doing something very strange using reflection, the code should not depend on the value of the execution time of the type argument. The current GenericClass in its current form is not very useful, because U has no restrictions, so the compiler will allow you to do only those things that are valid for all objects. You can view U in this context just like Object .