Распространение дженериков в Java - PullRequest
2 голосов
/ 08 мая 2020

У меня есть код Java с довольно сложным сценарием распространения дженериков:

public class Main {

  public static void parent(Parent<String> parent) {}

  public static void child(Child<String> parent) {}

  public static <T> Parent<T> makeParent() {
    return new Parent<>();
  }

  public static void main(String[] args) {
    // this works
    parent(makeParent());

    // this works
    Parent<String> objectParent = makeParent();
    child(objectParent.child());

    // this works
    child(Main.<String>makeParent().child());

    // this does not work
    child(makeParent().child());
  }

  static class Parent<T> {

    public Child<T> child() {
      return new Child<>();
    }

  }

  static class Child<T> {}

}
  1. Мне любопытно, почему и как это работает parent(makeParent());? Как делается вывод о замене T?

  2. А также почему это не работает child(makeParent().child());? Поскольку распространяется тот же тип generi c.

1 Ответ

2 голосов
/ 08 мая 2020

Что нужно помнить о выводе типа в цепочках вызовов, так это то, что вывод типа выполняется по мере продвижения по цепочке: если у вас есть a().b():

  • Вывод типа выполняется для a() first;
  • Затем выводится тип для a().b()

Итак:

  1. parent(makeParent()): тип makeParent() выводится в соответствии с тем, что совместимо с параметром parent(). Поскольку это будет принимать только Parent<String>, это предполагаемый тип.

  2. child(makeParent().child()): предполагается тип makeParent(); но нет никаких ограничений на тип (это не параметр внешнего child), поэтому предполагается, что он равен Parent<Object>; тогда типом makeParent().child() будет Child<Object>, что несовместимо с типом параметра child, отсюда и ошибка компилятора.

Досадно, что Java не 'Не откладывайте вывод типа makeParent() до тех пор, пока он не получит больше информации, а именно тот факт, что makeParent().child() должен быть совместим с каким-то конкретным типом.

Я полагаю, это сделано для ограничения сложности вывода : Я могу представить себе ситуацию, когда может потребоваться решить некоторый до неприличия сложный набор ограничений вывода типов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...