I found a bit of generic code and it has stumped me as to how it actually works. I don't understand where it gets the generic type that is used for T. This is an oversimplified example but I still don't understand how this is valid Java code.
public static void main(String[] args) {
System.out.print(get());
}
public static <T> T get()
{
return (T) getObj();
}
public static Object getObj()
{
return Boolean.FALSE;
}
Generics should be used instead of raw types ( Collection< T > instead of Collection , Callable< T > instead of Callable , …) or Object to guarantee type safety, define clear type constraints on the contracts and algorithms, and significantly ease the code maintenance and refactoring.
Generic Method: Generic Java method takes a parameter and returns some value after performing a task. It is exactly like a normal function, however, a generic method has type parameters that are cited by actual type. This allows the generic method to be used in a more general way.
You can get around the superfluous reference by providing a generic static factory method. Something like public static <T> GenericClass<T> of(Class<T> type) {...} and then call it as such: GenericClass<String> var = GenericClass. of(String. class) .
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
Java Generics - Type Inference. Type inference represents the Java compiler's ability to look at a method invocation and its corresponding declaration to check and determine the type argument(s). The inference algorithm checks the types of the arguments and, if available, assigned type is returned.
Generic Methods introduced you to type inference, which enables you to invoke a generic method as you would an ordinary method, without specifying a type between angle brackets. Consider the following example, BoxDemo, which requires the Box class:
The compiler infers the type String for the formal type parameter, T, of the constructor of this generic class (because the actual parameter of this constructor is a String object). Compilers from releases prior to Java SE 7 are able to infer the actual type parameters of generic constructors, similar to generic methods.
An invocation of a generic type is generally known as a parameterized type. To instantiate this class, use the new keyword, as usual, but place <Integer> between the class name and the parenthesis: Box<Integer> integerBox = new Box<Integer> ();
Type inference happens based on the callsite.
However, type inference only applies to return types if the return value is assigned to a variable. This is written in the spec
If the method result occurs in a context where it will be subject to assignment conversion, then [...]
Otherwise, any unresolved type parameters always become Object
.
In your example, that will work, because there is a print(Object)
overload.
On the other hand, look at this code:
print(get());
public void print(Boolean x) { }
public <T> T get() {
return (T) Boolean.FALSE;
}
This will give a compilation error, because the compiler infers get()
as returning Object
before looking at print()
.
In the code you wrote T is not bound to anything. Java will assign a type to T whenever you invoke the get
method and it will look at the type that you are expecting to get back... but that seems to be working only if you declare explicitly which type are you waiting for. Look at the following example:
public static void jump(String a) {
}
public static <T> T get() {
return (T) null;
}
public static void main(String[] args) {
//This works quite well, generic parameter T is inferred to be String
String blah = get();
jump(blah);
}
On the other hand
public static void jump(String a) {
}
public static <T> T get() {
return (T) null;
}
public static void main(String[] args) {
//This doesn't work, Java does not bind T to anything hence Object is used... and no jump for object is found
jump(get());
}
At least this is how it works on Java 6.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With