Können Sie eine Java -Klasse mit ABCL schreiben?
-
24-10-2019 - |
Frage
Gibt es eine Möglichkeit, eine Java -Klasse mit zu erstellen? Abcl (Das erweitert eine andere Klasse)?
Lösung
Man kann direkt eine Java -Klasse als JVM -Bytecode über die Funktionen im JVM -Paket schreiben, nämlich der Code, den der Compiler von ABCL verwendet. Ab ABCL-0.25.0 gibt es einen nicht unterstützten Code für a Java: Jnew-Runtime-Klasse-Methode Dies ermöglicht es, eine Java -Klasse dynamisch zu schreiben, die Lisp -Methoden für die Ausführung aufruft. Der Code verwendet Klassen aus dem ObjectWeb ASM BCEL das muss im JVM -Klassenpfad vorhanden sein. Genau welche Version der ASM BCEL -Bibliothek ist erforderlich und ob sie mit dem aktuellen ABCL funktioniert. ABCL -Ausgabe #153 Verfolgt die Arbeit, die erforderlich ist, um dies in der zeitgenössischen ABCL -Implementierung zu unterstützen.
Wenn man jedoch über eine vorhandene Java -Schnittstelle verfügt, für die man LISP -basierte Methoden zur Bereitstellung einer Implementierung verwenden möchte, ist der Prozess erheblich einfacher (und unterstützt!)
Die relevante Funktion ist Java: Jinterface-Implementierung, deren Verwendung in der gezeigt wird BankAccount Beispiel.
Für die Java -Schnittstelle definiert als
public interface BankAccount {
public int getBalance();
public void deposit(int amount);
public void withdraw(int amount);
}
Der folgende Lisp -Code erstellt im aktuellen JVM einen verwendbaren Java -Proxy:
(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)))))))
Um einen Verweis auf diese Implementierung von Java zu erhalten, verwendet man den Code in bankaAncount.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());
...
Andere Tipps
Dieses Beispiel zeigt, wie eine Java -Schnittstelle in ABCL implementiert werden kann.