8

В настоящее время я пишу компилятор Java и реализовал раздел 15.12.2.7. JLS7 (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2.7), один из самых раздражающих разделов спецификации. У меня все еще есть одна проблема, поскольку спецификация почему-то кажется неопределенной или неоднозначной. Моя проблема заключается в этой строке:Тип метода вывода в спецификации Java

lcta (U) =? если верхняя граница U - объект, иначе? extends lub (U, Object)

U - выражение произвольного типа. Какова верхняя граница выражения типа? Кроме того, почему lcta всегда является шаблоном?

Спецификация определяет

CandidateInvocation (G) = LCI (Inv (G)).

Теперь рассмотрим случай, когда Inv (G) = {List <String>}, то есть единственный возможный вызов кандидата - это один параметризованный тип. Теперь, в связи с правилом

LCI (G < X1, ..., Xn >) = G < ЛВТА (X1), ..., ЛВТА (Xn) >,

результат CandidateInvocation (G) = LCI ({Список < Строка >}) будет определяться как:

< Список ЛВТА (String) >

на мой взгляд, ЛВТА должен простофиля ly return String здесь, потому что, если List <String> - единственный возможный вызов, рекомендуется вывести список <String> в качестве аргумента. Однако определение lcta (U) диктует, что результат тоже? или ? extends lub (...), поэтому результат ВСЕГДА содержит подстановочный знак. Это кажется странным. Что я неправильно истолковываю здесь?

ответ

1

Я спросил в списке рассылки компилятор Dev и получил ответ:

Да, спецификация здесь не так. Правило для lcta (U) является просто полным дерьмом :). Кроме того, они заявили, что было бы даже лучше не называть lcta (U) вообще для одного аргумента и просто использовать U (поскольку наименьший аргумент общего типа для одного аргумента U всегда должен быть сам U).

6

Это похоже на ошибку спецификации. Пункт lcta(U) не существовал в JSL3. По-видимому, определение JLS3 lci(e1..en) является неполным, когда n=1, и новая спецификация пытается его исправить. Но исправить кажется тарабарщина, как вы рассуждали.

Javac7 вычисляет lci({ List<String> }) как List<String>, игнорируя добавленные предложения.

Эта проблема должна быть поднята до спецификаторов; не знаете, как с ними связаться. Вы можете попробовать openjdk compiler-dev список рассылки; на нем есть знающие люди.

+0

Я теперь реализовал lcta (U) = U, который, кажется, работает нормально. Я сообщу, найду ли я случаи, когда эта реализация приводит к неожиданным результатам.Кстати, не lub (U, Object) всегда U, так как Object всегда является супер классом U, и, таким образом, минимизированный стертый кандидат MEC из {U, Object} должен всегда давать U или один из его подклассов? Таким образом, правило действительно полное дерьмо. Единственное, что может быть полезно, это трансформировать? расширяет объект до?. Однако, поскольку U является выражением типа, он не может содержать подстановочные знаки, чтобы этот случай никогда не возникал ... действительно странно. – gexicide

+0

и хорошая идея с рассылкой, я думаю, что попробую там – gexicide

+0

Я думаю, lub (U, Object) = Object – irreputable

Смежные вопросы