I thought the Java compiler (Java 11) could infer by itself the actual generic type, if I gave it enough hints, for example when the generic type is a method parameter and I provide as a parameter an instance of the actual type.
For example, I have the following class:
public class Var<T>
{
public T value;
public Var(T value)
{
this.value = value;
}
}
Then, I try the following 3 attempts, which I expected all to compile:
//(1) Compilation error!
Var v = new Var(0);
++v.value;
//(2) Compilation error!
Var v = new Var<Integer>(0);
++v.value;
//(3) Compiles!
Var<Integer> v = new Var(0);
++v.value;
1) I would expect (1) to compile, because by using an Integer
(or int
) parameter, it may be enough for the compiler to know the actual type. So in ++v.value;
I would expect the compiler to know that the variable is an Integer
, but it does not. It still thinks it is an Object
.
2) Adds some explicit information. But still the compiler does not understand.
3) Compiles, as expected.
Then, I try type inference with the var
keyword:
//(4) Compilation error!
var v = new Var(0);
++v.value;
//(5) Compiles!
var v = new Var<Integer>(0);
++v.value;
4) Again, I would expect (4) to compile, since the type can be inferred from the parameter.
5) (After correcting my syntax:) Compiles, as expected.
Questions:
Could you explain why this code fails in the cases (1), (2), (4)?
Is there a way to make the var
keyword type inference work with such a class?
I would expect (1) to compile,
This is a raw type and is similar to writing
Var<Object> v = new Var<Object>();
but Object doesn't support ++
This is implied based on the class Var<T>
which is shorthand for class Var<T extends Object>
so if you have a raw type, it assumes the type T
extends.
Adds some explicit information. But still the compiler does not understand.
The code doesn't compile I suggest adding the information in the right place.
Var<Integer> v = new Var<>();
or
Var<Integer> v = new Var<Integer>();
Is there a way to make the var keyword type inference work with such a class
The var
is just a shorthand, and if the code wouldn't work without it, adding it won't help.
The correct syntax would be:
var v = new Var<Integer>(0);
new <Integer>Var(0)
is the obscure syntax for using a generic constructor (much the same as a generic method). You have a generic type.
The original code should be generating a ton of raw type warning messages.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.