你能用ABCL写一个Java类吗?

com*_*man 5 java jvm common-lisp abcl

有没有办法用ABCL创建一个Java类(扩展另一个类)?

小智 5

可以通过JVM包中的函数直接编写Java类作为JVM字节码,这是ABCL自己的编译器使用的代码.从abcl-0.25.0开始,JAVA的代码不受支持:JNEW-RUNTIME-CLASS方法允许动态编写一个调用Lisp方法执行的Java类.该代码使用ObjectWeb ASM BCEL中必须存在于JVM类路径中的类.究竟需要哪个版本的ASM BCEL库,以及它是否适用于当前的ABCL是未经测试的.ABCL问题#153跟踪在当代ABCL实施中支持这一点所需的工作.

但是如果有一个现有的Java接口,人们想要使用基于Lisp的方法来提供实现,那么这个过程要简单得多(并且支持!)

相关功能是JAVA:JINTERFACE-IMPLEMENTATION,其用途在BankAccount示例中进行了说明.

对于定义为的Java接口

public interface BankAccount {
  public int getBalance();
  public void deposit(int amount);
  public void withdraw(int amount); 
}
Run Code Online (Sandbox Code Playgroud)

以下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)))))))
Run Code Online (Sandbox Code Playgroud)

要从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());
  ... 
Run Code Online (Sandbox Code Playgroud)