Понимание захваченного преобразования

Я пытаюсь понять, как захваченное преобразование работает для подстановочных типов. В разделе JLS есть раздел:

Пусть G назовите объявление типового типа (§8.1.2, §9.1.2) с параметрами типа n A1,...,An с соответствующими границами U1,...,Un.

Существует преобразование захвата из параметризованного типа G<T1,...,Tn> (§4.5) к параметризованному типу G<S1,...,Sn>, где для 1 ≤ i ≤ n:

  • Если Ti является аргументом подстановочного типа (п. 4.5.1) формы ?, то Si является переменная нового типа, верхняя граница которой Ui[A1:=S1,...,An:=Sn] и нижняя граница которой является типом null (§ 4.1).

  • Если Ti является аргументом типа подстановки формы ? extends Bi, то Si является новая переменная типа, верхняя граница которой glb(Bi, Ui[A1:=S1,...,An:=Sn]), нижняя граница которой - тип null.

    glb(V1,...,Vm) определяется как V1 & ... & Vm.

    Это ошибка времени компиляции, если для любых двух классов (не интерфейсов) Viи Vj, Vi не является подклассом Vj или наоборот.

  • Если Ti является аргументом типа подстановки формы ? super Bi, то Si является переменная нового типа, верхняя граница которой Ui[A1:=S1,...,An:=Sn] и нижняя граница которой Bi.

  • В противном случае Si = Ti.

То, что мне не понятно, это Ui[A1:=S1,...,An:=Sn]. Что это значит? Я не смог найти определение для этого поиска через JLS.

Ответ 1

Сначала: определить подстановку.

[A1:=S1,...,An:=Sn] является замена в нотации JLS (§ 1.3), определяемая как:

Обозначение [F1:=T1,...,Fn:=Tn] означает замену Fi на Ti для 1 ≤ i ≤ n.

Заявление: [A1:=S1,...,An:=Sn] - это замена параметра типа (G) Ai для переменной типа Si для 1 ≤ i ≤ n. (также см. сноску )

Далее: рассмотрим, почему нам понадобится замена в первом случае. Из §5.1.10 (выделение добавлено для перехода домой в следующую точку):

Пусть G назовите объявление типового типа... с n введите параметры A1,...,An с соответствующими границами U1,...,Un.

То есть:

  • оценки U1,...,Un соответствуют параметрам типа A1,...,An.
  • неустановленное следствие: оценки U1,...,Un не соответствуют переменным типа S1,...,Sn.

Объединяя его: я сейчас заявляю очевидное, поскольку я уверен, что вы опередили меня, но...

Относительно правила для "Ti является аргументом типа подстановки... формы ?" )

Si - это новая переменная типа, верхняя граница которой Ui [A1:=S1,...,An:=Sn]

  • Si - это переменная типа
  • верхняя граница которой Ui
  • где (это подразумеваемый бит)
  • введите параметры A1,...,An, которые U1,...,Un соответствуют конкретно
  • были заменены переменными типа S1,...,Sn
  • make U1,...,Un соответствуют переменным типа S1,...,Sn

TL; DR

то есть. Это просто означает, что исходная верхняя граница Ui также является верхней границей для Si

Сноски

Полезно вспомнить из JLS что переменные типа и параметры типа не одно и то же (поэтому мы можем начать понимать, зачем нам нужна замена):

Переменная типа - это неквалифицированный идентификатор, используемый как тип в классе, интерфейсе, методе, и тела конструктора.

Переменная типа вводится объявлением параметра типа общего класса, интерфейса, метода или конструктора.

Ответ 2

Это означает "замену" переменных типа фактическими типами. Например

List<T>[T:=String]    =>    List<String>

Enum<E extends Enum<E>>
    A1=E
    U1=Enum<E>

Enum<?> capture convertion to  Enum<S1>
    U1[A1:=S1]   =>   Enum<S1>
    S1 upper bound is Enum<S1>

Синтаксис скорее всего заимствован из лямбда-калькуляции