ABCL (別のクラスを拡張する)を使用して Java クラスを作成する方法はありますか?
2 に答える
ABCL独自のコンパイラが使用するコードであるJVMパッケージの関数を介して、JavaクラスをJVMバイトコードとして直接書くことができます。abcl-0.25.0 の時点で、実行のために Lisp メソッドを呼び出す Java クラスを動的に記述できるようにするJAVA:JNEW-RUNTIME-CLASS メソッドのサポートされていないコードがあります。このコードは、JVM クラスパスに存在する必要があるObjectWeb ASM BCELのクラスを使用します。必要な ASM BCEL ライブラリの正確なバージョンと、現在の ABCL で動作するかどうかはテストされていません。ABCLの第 153号では、現在の ABCL 実装でこれをサポートするために必要な作業を追跡しています。
しかし、実装を提供するために Lisp ベースのメソッドを使用したい既存の Java インターフェースがある場合、プロセスはかなり単純になります (そしてサポートされます!)。
関連する関数は JAVA:JINTERFACE-IMPLEMENTATION で、その使用法はBankAccount の例で示されています。
として定義された Java インターフェースの場合
public interface BankAccount {
public int getBalance();
public void deposit(int amount);
public void withdraw(int amount);
}
次の Lisp コードは、現在の JVM で使用可能な Java プロキシを作成します。
(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());
...
この例は、ABCL で Java インターフェースを実装する方法を示しています。