Тип вывода: Generics, "var" - PullRequest
       29

Тип вывода: Generics, "var"

0 голосов
/ 29 октября 2018

Я думал, что компилятор Java (Java 11) мог бы выводить сам фактический универсальный тип, если бы я дал ему достаточно подсказок, например, когда универсальный тип является параметром метода, и я предоставляю в качестве параметра экземпляр фактического типа .

Например, у меня есть следующий класс:

public class Var<T>
{
    public T value;

    public Var(T value)
    {
        this.value = value;
    }
}

Затем я пробую следующие 3 попытки, которые, как я ожидал, все скомпилируют:

//(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) Я ожидаю, что (1) будет компилироваться, потому что при использовании параметра Integer (или int) может быть достаточно, чтобы компилятор знал фактический тип. Так что в ++v.value; я бы ожидал, что компилятор будет знать, что переменная Integer, но это не так. Он все еще думает, что это Object.

2) Добавляет некоторую явную информацию. Но все равно компилятор не понимает.

3) Компилируется, как и ожидалось.

Затем я пытаюсь определить тип с ключевым словом var:

//(4) Compilation error!
var v = new Var(0);
++v.value;

//(5) Compiles!
var v = new Var<Integer>(0);
++v.value;

4) Опять же, я ожидаю, что (4) скомпилируется, так как тип может быть выведен из параметра.

5) (После исправления моего синтаксиса :) Компилируется, как и ожидалось.

Вопросы:

Не могли бы вы объяснить, почему этот код не работает в случаях (1), (2), (4)?

Есть ли способ заставить вывод типа ключевого слова var работать с таким классом?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Правильный синтаксис будет:

var v = new Var<Integer>(0);

new <Integer>Var(0) - неясный синтаксис для использования универсального конструктора (во многом аналогичного универсальному методу). У вас есть универсальный тип.

Исходный код должен генерировать тонну необработанных предупреждений типа.

0 голосов
/ 29 октября 2018

Я бы ожидал (1) для компиляции,

Это необработанный тип, похожий на запись

Var<Object> v = new Var<Object>();

но Object не поддерживает ++

Это подразумевается на основе class Var<T>, что является сокращением для class Var<T extends Object>, поэтому, если у вас необработанный тип, предполагается, что тип T extends.

Добавляет некоторую явную информацию. Но все равно компилятор не понимает.

Код не компилируется. Я предлагаю добавить информацию в нужное место.

Var<Integer> v = new Var<>();

или

Var<Integer> v = new Var<Integer>();

Есть ли способ заставить вывод типа ключевого слова var работать с таким классом

var - это просто сокращение, и если код не будет работать без него, добавление не поможет.

...