Можете ли вы написать класс Java с ABCL?
-
24-10-2019 - |
Вопрос
Есть ли способ создать класс Java с Абкл (Это расширяет другой класс)?
Решение
Можно написать непосредственно написать класс Java в качестве Bytecode JVM через функции в пакете JVM, который является кодом, который использует собственный компилятор ABCL. По состоянию на ABCL-0.25.0, существует неподдерживаемый код для Java: метод класса Jnew-runtime который позволяет динамически писать класс Java, который вызывает методы LISP для выполнения. Код использует классы из объекта ASM Bcel который должен присутствовать в классе JVM. Какая версия библиотеки ASM BCEL необходима, и работает ли она с текущим ABCL, не проверена. ABCL выпуск #153 Отслеживает работу, необходимую для поддержки этого в современной реализации ABCL.
Но если у кого -то есть существующий интерфейс Java, для которого можно было бы использовать методы на основе LISP для обеспечения реализации, процесс значительно проще (и поддерживается!)
Соответствующая функция-Java: JInterface-внедрение, использование которого демонстрируется в Пример Bankaccount.
Для интерфейса Java, определяемого как
public interface BankAccount {
public int getBalance();
public void deposit(int amount);
public void withdraw(int amount);
}
Следующий код LISP создает полезную Java -прокси в текущем JVM:
(defparameter *bank-account-impl*
(let ((balance 1000))
(jinterface-implementation
"BankAccount"
"getBalance"
(lambda ()
balance)
"deposit"
(lambda (amount)
(let ((amount (jobject-lisp-value amount)))
(setf balance (+ balance amount))))
"withdraw"
(lambda (amount)
(let ((amount (jobject-lisp-value amount)))
(setf balance (- balance amount)))))))
Чтобы получить ссылку на эту реализацию из Java, использует код в Bankmainaccount.java
...
org.armedbear.lisp.Package defaultPackage
= Packages.findPackage("CL-USER");
Symbol bankAccountImplSymbol
= defaultPackage.findAccessibleSymbol("*BANK-ACCOUNT-IMPL*");
LispObject value = bankAccountImplSymbol.symbolValue();
Object object = ((JavaObject) value).getObject();
BankAccount account = (BankAccount) object;
System.out.println("Initial balance: " + account.getBalance());
account.withdraw(500);
System.out.println("After withdrawing 500: " + account.getBalance());
...
Другие советы
Этот пример Показывает, как реализовать интерфейс Java в ABCL.