General method call using <T>
I have a problem understanding such a generic method call:
object = ObjectGenerator.<T> getObject(objectName); Here is the context for the above situation:
class GenClass<T> { private T object; // ... some code public void initObject(String objectName) { object = ObjectGenerator.<T> getObject(objectName); } } class ObjectGenerator { public static <T extends Object> T getObject(String name) { // some code return someObject; } } The question is, what role does <T> play before calling getObject(objectName) ?
Note: in the specific example that you specified, ObjectGenerator.getObject(objectName); should compile fine.
In some situations, the type inference mechanism cannot decide what to:
T object; object = ObjectGenerator.getObject(objectName); return type must be T In this case, you need to help the compiler a bit by explicitly specifying the type of the returned result.
Here's a contrived example where you need to explicitly specify a generic type:
class Example { public static <T> List<T> m1() { return m2(Arrays.<T> asList()); //Arrays.asList() would not compile } public static <T> List<T> m2(List<T> l) { return l; } } object can be a child of type.
Of course, getObject better defined:
public static <T> T getObject(Class<T> objectClass, String name) { return objectClass.getConstructor(String.class).newInstance(name); //return objectClass.getConstructor().newInstance(); } Otherwise, a safe type construction is not possible due to the so-called type erasure.
I have found something here: https://stackoverflow.com/a/4126186/2704/ he can help you.
From what I read, a general can be represented, which the compiler should use to calculate the return type of the value, to pass the general direct
as a note, this also works great (check that the ObjectGenerator is different from T):
public class ObjectGenerator<X> { public static <T extends Object> Set<T> getObject(String name) { // some code return null; } } I do not completely agree with the accepted answer, which says:
In this case, you need to give the compiler a little help, explicitly indicating the type of return result.
It doesnβt sound like that. Since I understand the general method and type inference, the type enclosed in square brackets does not directly indicate the return type of the general method. Rather, the type T can be the type of the return type, the type of the argument, the local type of the variable associated with the general method.
In fact, thanks to the type input mechanism, in most cases we do not need to specify a type parameter T (not only in some situations). In your example, <T> can be safely excluded from the call to the ObjectGenerator.<T> getObject(objectName) , as in most other cases. This is because type T general method can be easily inferred from the type to which the result is assigned, or returned . In other words, since you declare a private T object before calling the method, the type T will be successfully inferred as T
My statement can be supported by the following expression of the final textbook :
Type inference is the ability of the Java compiler for each method to call and the corresponding declaration to determine the type of argument (or arguments) that make the call applicable. the inference algorithm determines the types of arguments and, if available, the type to which the result is assigned or is returned. Finally, the output algorithm tries to find the most specific type that works with all arguments.
Two examples of how output works:
static <T> T pick(T a1, T a2) { return a2; } Serializable s = pick("d", new ArrayList<String>()); Type T is inferred as Serializable based on the declared receiver type.
public static <U> void addBox(U u, java.util.List<Box<U>> boxes) {} BoxDemo.<Integer>addBox(Integer.valueOf(10), listOfIntegerBoxes); Type U is inferred as Integer based on the type of the argument passed (i.e., Integer.valueOf(10) is of type Integer ). Therefore, <Integer> can be safely excluded from the method call above.
To summarize, if we can not deduce a parameter of a universal method type from its argument type or the type that is assigned or return the result (when the method is called), we can safely omit the right of type specification before calling the method.
object = ObjectGenerator.getObject(objectName); always returns an Object because you are calling a static method. To explicitly get the generic object you used for T in your code,
object = ObjectGenerator.<T> getObject(objectName); <T> used in a static context. A non-static call is not required.