вызывать динамические и неявные методы - PullRequest
4 голосов
/ 21 августа 2011

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

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

Ответы [ 2 ]

13 голосов
/ 21 августа 2011

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

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

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

Динамический режим заключается в том, чтобы не беспокоиться о том, существует ли метод m в x во время компиляции, а искать его во время выполнения.Вот как обычно работает динамический язык, такой как JRuby или Groovy.В scala есть нечто связанное с чертой Dynamic (помечено как экспериментальное).

5 голосов
/ 21 августа 2011

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

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

Факторы Scala фактически разрешены статически и, таким образом, не связаны с invokedynamic. Подробнее о том, как это работает, см. В превосходном разоблачении Даниэля Собрала: Где Scala ищет следствия?

...