简体   繁体   中英

Type inference: Generics, "var"

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM