I am updating my 2.9.* project to 2.10. I have several classes for fundamental types (angles, lengths, etc) that seem like they are perfect candidates for value types. Unfortunately, my Java code that uses these types is not compiling, and I can't figure out why. I have simplified it down to a very simple set of code. Any suggestions would be much appreciated.
Angle class 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)
}
Angle Test Case (painfully written in Java)
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);
}
}
When I compile, I get this error:
AngleTest.java:19 incompatible types
found :double
required: com.example.units.Angle
Angle a = Angle.Zero();
^
It looks to me as if Angle.Zero is being returned as a double, not an Angle. I tried adding box/unbox methods, but continue to receive the same error. Again, any help would be greatly appreciated.
Scala compiler turns value classes into their unboxed type, which eliminates their cost for runtime. Inspecting the compiled class file for Angle
, you'll see:
public static double Zero();
So from Java's point of view, Angle.Zero returns a double; it's not aware of the semantics of Scala's value classes.
Angle's own methods, such as degrees
, get compiled into a) a static extension method that takes in the unboxed value (double
) b) an instance method:
public static double degrees$extension(double);
public double degrees();
Which means the latter can still be called on an instance of Angle
in Java:
Angle a = new Angle(0);
Assert.assertEquals(a.degrees(), 0, 1E-9);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With