вызывать динамические и неявные методы

Как я понял, прочитав этот пост о новом invokedynamic байт-кода в JDK 7 позволяет вызывать методы для объектов, которые не определены статически в классе объекта, и разрешать эти вызовы методов некоторым конкретным статическим методам в каком-либо другом классе путем перехвата целевого разрешения вызова метода (т. пост дает пример).

Означает ли это, что классы Java 7 могут иметь неявные методы, как в Scala? Если нет, то как разрешение неявного метода в Scala отличается от разрешения метода invokedynamic?


person Abhinav Sarkar    schedule 20.08.2011    source источник


Ответы (2)


Это совершенно не связано. Неявные значения в scala полностью разрешаются во время компиляции. Компилятор вставляет то, что вы могли бы написать сами. Если он не может этого сделать, во время компиляции возникает ошибка. InvokeDynamic — это поиск метода во время выполнения и сбой во время выполнения, если он не может быть найден.

В частности, если вы напишете в scala x.m(), где нет метода m типа x, он будет искать неявное преобразование, то есть функцию, скажем, f, которая находится в области видимости (в этот момент вы можете вызвать f), которая помечен как implicit, который будет принимать x в качестве параметра, и чей тип результата имеет метод m (в правилах намного больше подробностей, но это суть). Если он найдет такой метод, то заменит x.m() на правильно типизированный f(x).m(). С таким же успехом это могло быть написано в коде, и это должно было бы быть в java. Если такая функция f не может быть найдена, возникает ошибка времени компиляции.

Это происходит точно так же, если вы вызываете g(x), а x имеет неправильный тип для передачи в g. Если существует функция f такая, что f(x) имеет правильный тип, то она заменит код на g(f(x)). Опять же, вы могли бы написать это сами на простой scala, и опять же, если такого метода нет, он не скомпилируется.

Dynamic заключается в том, чтобы не слишком беспокоиться во время компиляции о том, есть ли метод m в x, и искать его во время выполнения. Так обычно работает динамический язык, такой как JRuby или Groovy. Есть что-то родственное в scala, черта Dynamic (помечена как экспериментальная).

person Didier Dupont    schedule 20.08.2011
comment
Итак, invokedynamic не может добавлять динамические методы в классы Java? - person Abhinav Sarkar; 21.08.2011
comment
В первую очередь, это изменение байт-кода (больше похоже на хитрый трюк с его семантикой, если я правильно прочитал пост, на который вы ссылаетесь), основная цель которого - упростить реализацию динамического языка на JVM. Разрешение динамического вызова в java (определенно не динамический язык) - это другой вопрос. Если они решат это сделать, InvokeDynamic сделает это более эффективным. Но такую ​​вещь можно реализовать на уровне языка, поскольку в виртуальной машине доступно отражение. - person Didier Dupont; 21.08.2011
comment
Быстро взглянул на JSR, и похоже, что он действительно сделает динамический вызов доступным в java (если я правильно понимаю, ссылка может быть приведена к Dynamic без проверки во время выполнения, и вызовы, сделанные по ссылке, рассматриваемой как Dynamic компилятор динамический). Тем не менее, это не имеет никакого отношения к неявным свойствам scala. - person Didier Dupont; 21.08.2011
comment
@didierd Согласно [1], интерфейс java.dyn.Dynamic не превратился в язык Java. Вместо этого следует выполнять рефлексивные вызовы с помощью java.lang.invoke.MethodHandle, чтобы получить динамический байт-код вызова из Java. Трейт Scala Dynamic в основном является тем, чем должен был быть java.dyn.Dynamic. Ссылка: [1] stackoverflow.com/questions /7031634/ - person Kipton Barros; 21.08.2011
comment
@Kipton Спасибо за эту информацию. - person Didier Dupont; 22.08.2011

Вызов динамического байт-кода поможет ускорить динамические языки в JVM. Это также ускорит доступ к структурным типам в Scala. Альтернативой invokedynamic (и единственным вариантом до JDK 7) является отражение, которое очень медленно.

Язык Java является статически типизированным и не имеет функций, использующих invokedynamic (за исключением явных вызовов рефлексивных методов с использованием java.lang.invoke.MethodHandle, согласно этот вопрос).

Неявные значения Scala на самом деле разрешаются статически и, таким образом, не связаны с invokedynamic. Для получения подробной информации о том, как это работает, см. отличный обзор Даниэля Собрала: Где Scala ищет имплициты?

person Kipton Barros    schedule 20.08.2011