Frage

Ich versuche, Scala-Code in meine vorhandene Java-App einzufügen.(Also, wie gesagt, ich möchte etwas mehr Spaß).

Ich erstelle ein Singleton-Zeug in Scala

ScalaPower.scala

    package org.fun
    class ScalaPower
    object ScalaPower{
      def showMyPower(time:Int) = {
        (0 to time-1).mkString(", ")
      }
    }

Jetzt in OldJava.java

class OldJava {
  public void demo(){
    System.out.println(?)
  }
}

Was soll ich ausfüllen? ? damit Java die showMyPower-Methode aufruft?Ich habe beides ausprobiert org.fun.ScalaPower.showMyPower(10) Und org.fun.ScalaPower.getInstance().showMyPower(10) aber keines funktioniert.

(Dekompilieren Sie die Klassendatei mit Jad und zeigen Sie mir nichts als unsinnigen Code.)

BearbeitenIch entferne die class ScalaPower Deklaration und Scala erzeugen wie erwartet die statische Methode.(Ruf an org.fun.ScalaPower.showMyPower(10) funktioniert einfach).

Ich frage mich, ob es ein Fehler im Scala-Compiler ist oder nicht

War es hilfreich?

Lösung

Ich denke, das deckt es indirekt ab:

Begleitobjekte und statische Java -Methoden

Es gibt noch eine Sache zu wissen über Begleitobjekte.Wenn Sie eine Hauptmethode definieren, die als Einstiegspunkt für eine Anwendung verwendet werden soll, müssen Sie sie in ein Objekt einfügen.Zum Zeitpunkt dieses Schreibens können jedoch die Hauptmethoden in einem Begleitobjekt nicht definiert werden.Aufgrund von Implementierungsdetails im generierten Code findet die JVM die Hauptmethode nicht.Dieses Problem kann in einer zukünftigen Veröffentlichung gelöst werden.Im Moment müssen Sie jede Hauptmethode in einem Singleton-Objekt (dh einem „Nicht-Kompanon" -Objekt) [scalatips] definieren.Betrachten Sie das folgende Beispiel für ein einfaches Personen- und Begleitobjekt, das versucht, Main zu definieren.

Wie hier gefunden: http://programming-scala.labs.oreilly.com/ch06.html

Kurz gesagt, da Ihr Objekt ein Begleitobjekt ist (eine Begleitklasse hat), können Sie es nicht wie erwartet aufrufen.Wie Sie festgestellt haben, wird es funktionieren, wenn Sie die Klasse loswerden.

Andere Tipps

Normalerweise ist es besser, direkt von seiner eigenen Klasse aus auf den Singleton zuzugreifen.

In diesem Fall:

org.fun.ScalaPower$.MODULE$.showMyPower(10);

Ohne zu sehr auf die Implementierungsdetails einzugehen, unterscheidet Scala Namensräume zwischen Objekt und Klasse/Merkmal.Das bedeutet, dass sie denselben Namen verwenden können.Ein Objekt hat jedoch eine Klasse und benötigt daher einen verstümmelten Namen in der JVM.Die aktuellen Scala-Konventionen bestehen darin, am Ende des Modulnamens ein $ hinzuzufügen (für Module der obersten Ebene).Wenn das Objekt in einer Klasse definiert ist, lautet die Konvention meiner Meinung nach OuterClass$ModuleName$.Um die Singleton-Eigenschaft des ScalaPower-Moduls zu erzwingen, gibt es auch ein statisches MODULE$-Mitglied der ModuleName$-Klasse.Dies wird zum Zeitpunkt des Ladens der Klasse initialisiert, um sicherzustellen, dass es nur eine Instanz gibt.Ein Nebeneffekt davon ist, dass Sie es tun sollten nicht Führen Sie irgendeine Art von Sperrung im Konstruktor eines Moduls durch.

Auf jeden Fall hat Scala auch einen statischen Weiterleitungsmechanismus integriert, der die Dinge für Java schöner macht.Hier werden statische Methoden der ScalaPower-Klasse geschrieben, die lediglich ScalaPower$.MODULE$.someMethod() aufrufen.Wenn Sie auch eine Begleitklasse definieren, sind die generierten Weiterleitungen begrenzt, da Sie keine Namenskonflikte mit statischen Methoden und Methoden auf Instanzebene in der JVM haben dürfen.Ich denke, in 2.8.0 bedeutet das, dass Sie Ihre statischen Weiterleitungen verlieren, wenn Sie ein Begleitobjekt haben.

In diesem Fall wäre es eine „Best Practice“, immer die ScalaPower$.MODULE$-Referenz anstelle einer statischen Weiterleitung zu verwenden, da die Weiterleitung bei Änderungen an der ScalaPower-Klasse verschwinden könnte.

BEARBEITEN:Tippfehler

Welche Fehler sind bei Ihnen aufgetreten?Verwenden Sie Ihr Scala-Beispiel und die folgende Java-Klasse:

cat test.java:


import org.fun.*;

public class test {
    public static void main(String args[]) {
       System.out.println("show my power: " + ScalaPower.showMyPower(3));       
    }
}

Und führe es wie folgt aus:

java -cp .:<Pfad zu/scala/installationsverzeichnis>/lib/scala-library.jar test

gibt mir die Ausgabe:

show my power: 0, 1, 2

Bedenken Sie, dass die Aktie javap Mit dem Tool können Sie sehen, was der Scala-Compiler produziert.Natürlich wird Ihre Frage dadurch nicht direkt beantwortet, aber wenn Sie lediglich an die Codegenerierungsmuster erinnert werden möchten, ist dies ausreichend.

Danach

class ScalaPower 
object ScalaPower{
  def showMyPower(time:Int) = {
    (0 to time-1).mkString(", ")
  }
}

ScalaPower.showMyPower(10) Funktioniert wie erwartet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top