Вывод типа локальной переменной с условным (троичным) оператором разных типов - PullRequest
1 голос
/ 01 мая 2019
var test = "Hello World!";

В Java 10+ вышеупомянутый фрагмент компилируется, и test выводится как String во время компиляции.

Однако мы можем использовать условный (троичный) оператор для возврата различных типов, таких как:

var test = new Random().nextBoolean() ? "Hello World!" : 123;

Если бы мы печатали test.getClass() во время выполнения, он вывел бы либо:

  • класс java.lang.String
  • класс java.lang.Integer

Это имеет смысл, но что будет тип test во время компиляции? Это будет Object или что-то еще?

1 Ответ

3 голосов
/ 01 мая 2019

Интересно, что Intellij говорит мне, что тип test не Object, а скорее этот зверь:

java.io.Serializable & Comparable<? extends java.io.Serializable & Comparable<?> & constant.Constable & constant.ConstantDesc> & constant.Constable & constant.ConstantDesc

Причина, по которой это так, заключается в том, что компилятор определяет тип переменной как ближайший общий суперкласс между String и Integer, которые фактически Serializable, Comparable, Constable и ConstantDesc в Java 12.

Есть интересная статья, в которой подробно рассматриваются невозможные типы , которые называются этими типами (поскольку они могут быть определены только компилятором): Представление неосуществимого и невозможного с помощью JDK 10 «вар»

Если бы мы возвращали объекты, которые совершенно не связаны, такие как Integer и ByteArrayOutputStream, то мы увидели бы, что Java выводит тип времени компиляции test как Object:

var test = new Random().nextBoolean() ? 123 : new ByteArrayOutputStream();
...