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

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

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

2 ответа

Решение

Это совершенно не связано. Последствия в 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)), Опять же, вы могли бы написать это сами в простой скале, и опять же, если такого метода нет, он не скомпилируется.

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

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

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

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

Другие вопросы по тегам