Ich habe versucht, eine Java-Methode von ABCL zu verwenden

Einführung

In diesem Artikel verwenden wir ABCL (Armed-Bear-Common Lisp), eines unserer Common Lisp-Verarbeitungssysteme, das mit JVM arbeitet, um Klassen und Methoden zu betreiben, die in Java geschrieben sind. Das grundlegende Verfahren ist unten gezeigt.

** "Es wird nur API für Java bereitgestellt, aber ich möchte die Anwendung mit Common Lisp (im Folgenden als CL bezeichnet) verwenden!" **. Es gibt, richtig? Ja, da bin ich mir sicher.

** "Aber es gibt fast keine japanischen Dokumente, ich bin nicht sehr gut in Clojure und es ist schwer, anders als Lisp zu schreiben!" ** Ich bin nicht sicher, ob jemand da ist, aber dieser Artikel basiert auf ABCL für diese Leute. Dies ist ein Artikel, der die Grundlagen des Inneren beschreibt.

In diesem Artikel werden nur einfache Java-Methoden von CL aufgerufen. Ich werde in einem anderen Artikel über das Durcheinander der Details schreiben. Wenn Sie also danach suchen, erhalten Sie möglicherweise nichts. Daher wird empfohlen, den Browser zurückzusetzen.

Referenzdokumente

Dies war am hilfreichsten (oder nur).

Anfangs habe ich mich darauf bezogen, aber ich habe die Bedeutung nicht wirklich verstanden und war süchtig danach.

Wenn Sie sich verlaufen, ist es möglicherweise eine gute Idee, den Quellcode zu drücken.

Informationen über ABCL sind im Grunde genommen hier, oder?

Leider gibt es kein Dokument für diejenigen, die nur Japanisch lesen oder nicht lesen können. Es ist nicht in so schwierigem Englisch geschrieben, also geben Sie bitte Ihr Bestes, um es zu lesen.

Ich hoffe, dieser Artikel gibt Ihnen einen Eindruck von den Grundlagen!

Jetzt werde ich die ABCL-Spezifikationen für den Aufruf von Java aus Common Lisp erläutern.

Ausführungsumgebung

Schauen wir uns für alle Fälle diese Ausführungsumgebung an. Es sollte wahrscheinlich auch auf anderen Plattformen funktionieren. Ich habe es nicht überprüft. .. ..

Java statischer Methodenaufruf

Zunächst werde ich erklären, wie eine statische Methode aufgerufen wird. Der einfache Java-Code, der für diesen Aufruf verwendet wird, ist dieser.

Calc.java


public class Calc {
    public static int addTwoNumbers(int a, int b) {
        return a + b;
    }
}

Als statische Methode der Calc-Klasse führt sie auf einfache Weise ** zwei Argumente vom Typ Integer aus und gibt deren Summe als Rückgabewert zurück **. Nennen wir diese addTwoNumbers-Methode von Common Lisp. Der Code sieht so aus (↓)

calc.lisp


(defun add-two-num (num1 num2)
  (let ((result (jstatic "addTwoNumbers" "Calc" num1 num2)))
    result))

jstatic ist eine integrierte Funktion zum Aufrufen statischer Java-Methoden. Das erste Argument ist der Name der aufzurufenden Methode (Zeichenfolge) **, das zweite Argument ist die Klasse, zu der die Zielmethode gehört **, und das dritte und nachfolgende Argument sind die ** Methodenargumente **. Bei der Auswertung wird das Ausführungsergebnis der Methode zurückgegeben, an das Ergebnis gebunden und am Ende ausgegeben.

Selbst wenn Sie sich das Beispielprogramm ansehen, wird nur dieses geschrieben, aber natürlich kann der Java-Code nicht so aufgerufen werden, wie er ist. Kompilieren Sie ihn also und übergeben Sie ihn über den Klassenpfad. Wenn ich es für Leute schreibe, weil ich nicht viel darüber weiß,

$ javac Calc.java
$ ls
Calc.class Calc.java calc.lisp

Wenn es wird, ist es ein Erfolg. Wenn die Kompilierung nicht erfolgreich ist, stimmt etwas nicht und überprüfen Sie es erneut. Dabei kann es sein, dass bei dieser Codelänge keine Fehler auftreten.

Fahren wir mit REPL fort und nennen es tatsächlich!

CL-USER> (load "/Path/to/calc.lisp")
T
CL-USER> (add-to-classpath "/Path/to/Calc.java/")
("/Path/to/java-class")
CL-USER> (add-two-num 2 3)
5
CL-UER> (add-two-num -1 9)
8

Sie können es richtig nennen! add-to-classpath ist die in ABCL integrierte Funktion zum Übergeben von Pfaden an Java-Klassendateien. In Java können Sie den Klassenpfad übergeben, dies ist jedoch dynamischer und leichter zu verstehen (persönliche Ansicht).

Java dynamischer Methodenaufruf

Ich bin nicht so glücklich, nur die statische Methode aufrufen zu können. Überprüfen wir also den dynamischen Versand der Methode. Der für diesen Test verwendete Code lautet wie folgt.

Hero.java


public class Hero {
    private int hp;
    private int mp;

    public Hero() {
       hp = 100;
       mp = 100;
    }

    public void getDamage(int damage){
       hp -= damage;
    }

    public void useMagic(int consumption){
       mp -= consumption;
    }

    public String showStatus(){
       return "HP: "+hp+", MP: "+mp;
    }

    public static void main(String[] argv){
       Hero hero = new Hero();
    }
}

Es gibt einen Helden, der bei seiner Geburt "HP: 100" und "MP: 100" hat. Es erleidet eine gewisse Menge an Schaden, wenn es angegriffen wird, und verbraucht MP, wenn es Magie einsetzt. Wenn Sie den Status überprüfen, werden die verbleibenden HP und MP angezeigt.

Bitte denken Sie an diese Art von Klassendesign und denken Sie, dass Sie eine Klasse wie diese definiert haben.

hero.lisp


(add-to-classpath "/Path/to/java-class-file")
(defun hero-status ()
  (let* ((hero-class (jclass "Hero"))
	 (hero-instance (jnew (jconstructor "Hero")))
	 (method (jmethod hero-class "showStatus"))
	 (result (jcall method hero-instance)))
    result))

Instanziieren Sie zuerst diese Hero-Klasse und rufen Sie die showStatus-Methode auf. Der Ausgangszustand "HP: 100, MP: 100" sollte ausgegeben werden.

Früher habe ich Add-to-Classpath auf der obersten Ebene von REPL ausgewertet, aber wenn Sie es in die Lisp-Datei einfügen, wird es natürlich beim Laden ausgeführt.

jclass verwendet eine Zeichenfolge als Argument und gibt eine Java-Klassenreferenz mit dem Namen dieser Zeichenfolge zurück. Was hier zurückgegeben wird, ist ein Klassenobjekt, keine Instanz.

jnew nimmt ein Konstruktorobjekt als Argument und erstellt eine Instanz. Bitte beachten Sie, dass es nur instanziiert werden kann, wenn das Konstruktorobjekt von (jconstructor "Klassenname (Zeichenfolge)") [^ Hinweis 1] erfasst wurde.

jmethod ruft die Methode ab, die als Objekt aufgerufen werden soll. Übergeben Sie das Java-Klassenobjekt und den Methodennamen sowie gegebenenfalls die Argumenttypklasse [^ Hinweis 2].

Übergeben Sie abschließend das zuvor erfasste Methodenobjekt und das Instanzobjekt an jcall und führen Sie die Methode aus.

Wenn Sie es tatsächlich ausführen, sollte es wie folgt aussehen.

CL-USER> (load "/Path/to/hero.lisp")
T
CL-USER> (hero-status)
"HP: 100, MP: 100"

Führen Sie anschließend nach Verwendung der HP-Reduktionsmethode und der MP-Reduktionsmethode die Statusbestätigungsmethode aus. Beide Methoden subtrahieren den Wert, indem sie den zu reduzierenden Wert an das Argument übergeben.

Der Lisp-Ausdruck zum Anrufen sieht folgendermaßen aus.

hero-extend.lisp



(defun extended-hero-status (hp mp)
  (let* ((hero-class (jclass "Hero"))
	 (hero-instance (jnew (jconstructor "Hero")))
	 (java-int-class (jclass "int"))
	 (get-damage (jmethod hero-class "getDamage" java-int-class))
	 (use-magic (jmethod hero-class "useMagic" java-int-class))
	 (method (jmethod hero-class "showStatus")))
    (jcall get-damage hero-instance hp)
    (jcall use-magic hero-instance mp)
    (let (result (jcall method hero-instance))
      result)))

Es wird auf Java-ähnliche Weise geschrieben, aber wenn Sie diese Funktion tatsächlich bewerten,

CL-USER> (load "/Path/to/exted-hero.lisp")
T
CL-USER> (extended-hero-status 5 10)
"HP: 95, MP: 90"

Ich denke, dass Sie sehen können, dass es richtig funktioniert.

abschließend

Was haben Sie gedacht. Hast du das Gefühl bekommen? Mit ABCL ist es möglicherweise möglich, Java-Bibliotheken mit ComonLisp relativ einfach zu verwenden und verschiedene in der Java-Sprache geschriebene Programme in CL-Projekte zu integrieren.

Obwohl diesmal nicht eingeführt, ist es natürlich möglich, Common Lisp aus der Java-Sprache aufzurufen. Weitere Informationen finden Sie in der oben genannten Benutzerreferenz.

Wir freuen uns auf Ihre Anregungen und Eindrücke von Fehlern.

[^ Anmerkung 1]: Ich war süchtig danach, weil ich das Argument von jnew nicht verstand. [^ Anmerkung 2]: Anstatt das Argument selbst hier zu übergeben, übergeben Sie das Typklassenobjekt des Arguments. Insbesondere wird die zu versendende Methode durch Übergeben von so etwas wie (jclass "int") bestimmt.

Recommended Posts

Ich habe versucht, eine Java-Methode von ABCL zu verwenden
[Java] Ich habe versucht, mit der Grabmethode ein Labyrinth zu erstellen ♪
Java Ich habe versucht, einen einfachen Block zu brechen
Ich habe versucht, den Block mit Java zu brechen (1)
Ich habe versucht, Java in einem Mac-Terminal auszuführen
[JDBC] Ich habe versucht, den SQLite3-Datenbankzugriff von Java in eine Methode für jede SQL-Anweisung umzuwandeln.
Rufen Sie eine Methode mit Kotlins Rückrufblock von Java aus auf
Ich habe versucht, eine Clova-Fähigkeit in Java zu erstellen
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
Ich habe versucht, Log4j2 auf einem Java EE-Server zu verwenden
Ich habe versucht, nativen Java / Objective-C-Code von Flutter aus aufzurufen
Ich habe versucht, mit OCR eine PDF-Datei mit Java zu verarbeiten
Ich habe einen Wrapper erstellt, der KNP von Java aus aufruft
Ich habe versucht, ein Aktienchart mit Java (Jsoup) zu kratzen.
Erstellen Sie eine Java-Methode [Memo] [java11]
Ich habe Drools (Java, InputStream) ausprobiert.
Ich habe versucht, Java REPL zu verwenden
Ich habe versucht, Metaprogrammierung mit Java
Ich habe versucht, mit Chocolatey eine Java8-Entwicklungsumgebung zu erstellen
Ich habe versucht, eine Java EE-Anwendung mit OpenShift zu modernisieren.
[JDBC] Ich habe versucht, von Java aus auf die SQLite3-Datenbank zuzugreifen.
Ich habe versucht, in Java von einer Zeichenfolge in einen LocalDate-Typ zu konvertieren
Ich habe einen RESAS-API-Client in Java erstellt
Ich habe versucht, eine PDF-Datei mit Java part2 zu verarbeiten
Ich habe ein PDF mit Java erstellt.
Ich habe eine shopify App @java erstellt
Ich habe ein wenig digdags docker.run_options ausprobiert
Eine Person, die C ++ schreibt, hat versucht, Java zu schreiben
Führen Sie eine Batchdatei von Java aus
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, UDP mit Java zu kommunizieren
Greifen Sie über eine Java-Anwendung auf Teradata zu
Ich habe versucht, die Methode zu erklären
Ich habe das Java-Framework "Quarkus" ausprobiert.
Ich habe versucht, die Java8 Stream API zu verwenden
Ich habe versucht, JWT in Java zu verwenden
Ich habe versucht, das Java-Lernen zusammenzufassen (1)
Ich habe jetzt versucht, Java 8 zusammenzufassen
Ich habe versucht, Java Memo LocalDate zu verwenden
Ich habe versucht, Google HttpClient von Java zu verwenden
[Anmerkung] Was ich in einem halben Jahr von unerfahrenen (Java) gelernt habe
[Anmerkung] Was ich in einem halben Jahr von unerfahrenen (Java) gelernt habe (1)
Erstellt eine Methode zum Anfordern von Premium Friday (Java 8-Version)
[Anmerkung] Was ich in einem halben Jahr von unerfahrenen (Java) gelernt habe (3)
Ich habe versucht, eine C-Sprachprogrammquelle aus cURL zu generieren
Ich habe versucht, die Elasticsearch-API in Java zu verwenden
Ich habe ein Kalenderproblem mit Ruby versucht
Java-Methode
Java (Methode)
Ich habe versucht, UICollectionViewListCell zu verwenden, das von Xcode12 hinzugefügt wurde.
Ich habe versucht, Java mit einer Reihe zu lernen, die Anfänger klar verstehen können
Rufen Sie Java-Methoden aus JavaScript auf, das in Java ausgeführt wird
Ich habe Cassandras Object Mapper für Java ausprobiert
Ich habe versucht, Java-Lambda-Ausdrücke zusammenzufassen
Java9 war enthalten, also habe ich jshell ausprobiert.
Ich habe das neue Yuan-Problem in Java ausprobiert
Versuchen Sie, Kubernetes Job von Java aus auszuführen
Ich habe versucht, ein wenig mit BottomNavigationView zu spielen ①
Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden
Java-Methode
[Java] -Methode