Всякий раз, когда программный код, написанный на одном языке программиро_ вания, обращается к программному коду, написанному на другом языке про_ граммирования, необходимо учитывать, как отображаются типы данных в од_ ном языке программирования на типы данных в другом языке программирова_ ния.1 Предположим, что имеется необходимость присвоить значения типов java.lang.String и java.lang.Integer переменным в объекте Bindings. Когда Java_ Script_сценарий обратится к этим переменным, значения каких типов он обна_ ружит? А если результатом работы JavaScript_сценария будет логическое значе_ ние, значение какого типа вернет метод eval()?
В случае Java и JavaScript ответить на этот вопрос достаточно просто. Когда в объ_ екте Bindings сохраняется Java_объект (просто не существует способа сохранения значений элементарных типов), он преобразуется в JavaScript_значение в соот_ ветствии со следующими правилами:
• Объекты логических значений преобразуются в логический JavaScript_тип.
• Все объекты java.lang.Number преобразуются в JavaScript_числа.
• Java_объекты Character и String преобразуются в JavaScript_строки.
• Java_значение null преобразуется в JavaScript_значение null.
• Все остальные Java_объекты просто обертываются в JavaScript_объект Java_ Object (подробнее о типе JavaObject рассказывается далее в этой главе, где речь идет об организации взаимодействий с Java_объектами из JavaScript_ сценариев).
Есть несколько замечаний по поводу преобразования чисел. Все Java_числа пре_ образуются в JavaScript_числа. Это относится к типам Byte, Short, Integer, Long,
Float, Double, а также java.math.BigInteger и java.math.BigDouble. Специальные ве_ щественные значения, такие как Infinity и NaN, поддерживаются обоими языками и легко преобразуются один в другой. Обратите внимание, числовой JavaScript_ тип основан на 64_разрядном формате представления вещественных чисел и соот_
1 И вообще следует учитывать наличие типов, представимых в одном из языков, но отсутствующих в другом. В этом случае может оказаться необходимым моделиро_ вание отсутствующего типа искусственным пользовательским типом. – Примеч. науч. ред.
12.1. Встраивание JavaScript
ветствует Java_типу double. Не все значения Java_типа long могут быть преобразо_ ваны в тип double без потери точности, поэтому в случае передачи JavaScript_сце_ нариям значений типа long данные могут быть потеряны. То же относится к ти_ пам BigInteger и BigDecimal: младшие разряды числа могут оказаться утраченны_ ми, если числовые значения в Java будут иметь более высокую точность, чем может быть представлена в JavaScript. Или если числовое значение в Java будет больше, чем Double.MAX_VALUE, оно преобразуется в JavaScript_значение Infinity.
Преобразования в обратном направлении выполняются аналогичным образом. Когда JavaScript_сценарий сохраняет значение в переменной (т. е. в объекте Bindings) или вычисляется значение JavaScript_выражения, на стороне Java_ программы преобразование типов значений выполняется в соответствии со сле_ дующими правилами:
• JavaScript_значения логического типа преобразуются в Java_объекты Boolean.
• JavaScript_значения строкового типа преобразуются в Java_объекты String.
• JavaScript_значения числового типа преобразуются в Java_объекты Double. Значения Infinity и NaN преобразуются в соответствующие Java_значения.
• JavaScript_значения null и undefined преобразуются в Java_значение null.
• Объекты и массивы JavaScript преобразуются в Java_объекты неопределен_ ного типа. Эти значения могут передаваться обратно JavaScript_сценарию, но имеют прикладной интерфейс, который не предназначен для использования в программах на языке Java. Обратите внимание: объекты_обертки типа String, Boolean и Number языка JavaScript преобразуются в Java_объекты неоп_ ределенного типа, а не в значения соответствующего им типа на стороне Java.