2011-01-24 72 views

回答

5

可以通過JVM包中的函數直接編寫Java類作爲JVM字節碼,JVM包是ABCL自己的編譯器使用的代碼。從abcl-0.25.0開始,JAVA:JNEW-RUNTIME-CLASS method不支持代碼,允許動態編寫調用Lisp方法執行的Java類。該代碼使用ObjectWeb ASM BCEL中必須存在於JVM類路徑中的類。究竟需要哪種版本的ASM BCEL庫,以及它是否適用於當前的ABCL是未經測試的。 ABCL問題#153追蹤在當代ABCL實施中支持這項工作所需的工作。

但是,如果一個人有一個現有的Java接口,其中一個想用Lisp語言爲基礎的方法,以提供一個實現,這個過程是相當簡單(!和支持)

相關的功能是JAVA:JINTERFACE的實現其使用證明在BankAccount example

對於定義爲

public interface BankAccount { 
    public int getBalance(); 
    public void deposit(int amount); 
    public void withdraw(int amount); 
} 

以下Lisp代碼的Java接口在當前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()); 
    ... 
相關問題