2013-03-31 6 views
9

Ich aktualisiere mein 2.9. * Projekt auf 2.10. Ich habe mehrere Klassen für grundlegende Typen (Winkel, Längen usw.), die wie perfekte Kandidaten für Werttypen aussehen. Leider kompiliert mein Java-Code, der diese Typen verwendet, nicht, und ich kann nicht herausfinden, warum. Ich habe es auf einen sehr einfachen Code reduziert. Irgendwelche Vorschläge würden sehr geschätzt.mit Scala 2.10.1 Werttypen in Java

Angle Klasse Definition (scala)

package com.example.units 

class Angle(val radians : Double) extends AnyVal 
{ 
    def degrees = radians * 180.0/math.Pi 
} 

object Angle 
{ 
    val Zero = new Angle(0) 
} 

Winkel Test Case (schmerzlich in Java geschrieben)

package com.example.units; 

import junit.framework.Assert; 
import org.junit.Test; 

public class AngleTest 
{ 
    @Test 
    public static void TestZero() 
    { 
     Angle a = Angle.Zero(); 
     Assert.assertEquals(a.degrees(), 0, 1E-9); 

    } 

} 

Wenn ich kompilieren, bekomme ich diesen Fehler:

AngleTest.java:19 incompatible types 
found :double 
required: com.example.units.Angle 
Angle a = Angle.Zero(); 

      ^

Es sieht aus s an mich, als ob Angle.Zero als Double, nicht als Angle zurückgegeben wird. Ich habe versucht, Box/Unbox-Methoden hinzuzufügen, aber weiterhin den gleichen Fehler zu erhalten. Auch hier würde jede Hilfe sehr geschätzt werden.

Antwort

10

Der Scala-Compiler wandelt die Werteklassen in ihren ungefüllten Typ um, wodurch ihre Kosten für die Laufzeit entfallen. Inspizieren der kompilierten Klassendatei für Angle, werden Sie sehen:

public static double Zero(); 

So von Java-Sicht, Angle.Zero gibt eine doppelte; es ist sich der Semantik der Scala-Wertklassen nicht bewusst.

eigenen Methoden-Winkel, wie degrees, eine statische Dehnung Verfahren erhalten, die in dem unboxed Wert (double) b) eine Instanzmethode nimmt kompilierten in a):

public static double degrees$extension(double); 
public double degrees(); 

denen letztere bedeutet noch sein kann Eine Instanz von Angle in Java aufgerufen:

Angle a = new Angle(0); 
Assert.assertEquals(a.degrees(), 0, 1E-9); 
+0

Vielen Dank für die Antwort. Ich verwende Factory-Methoden in meinen Companion-Klassen (Angle.fromDegrees(), Angle.fromRadians() usw.), um die Lesbarkeit zu verbessern. Im Augenblick haben alle diese Methoden das gleiche Problem wie oben beschrieben. Es scheint mir, dass es einen Weg geben sollte, dies zum Funktionieren zu bringen. – fbl

+1

Ich bin definitiv neugierig, einen Weg zu finden, damit es funktioniert. Nachdem Sie einige Umgehungslösungen ausprobiert haben, scheint nichts elegant zu sein (zum Beispiel könnten Sie in Ihren Java-Tests den vom Aufruf .Zero() empfangenen Wert in einem Winkel umbrechen, was aber die Lesbarkeit einschränkt). Ich denke, die Hauptursache ist, dass Scalas Wertklassen nicht für die gleiche Interoperabilität mit Java ausgelegt sind wie normale Klassen; Sie sind lediglich eine Abstraktion zur Kompilierungszeit, um Ihren Scala-Code zu vereinfachen. Ich schlage vor, in Ihrem Fall regelmäßig Unterricht zu nehmen. –

+0

Leider bin ich zu demselben Schluss gekommen. Wenn das kein Bug ist, dann ist es zumindest ein Designfehler mit Werttypen. Eine der Stärken von Scalas ist seine Fähigkeit, nativ mit Java Code zu interagieren. Ich werde es vermeiden, sie zu benutzen, bis es angesprochen wird. – fbl