我将2.9。*项目更新为2.10。我有几个基本类型(角度,长度等)的类,看起来它们是值类型的完美候选者。不幸的是,我使用这些类型的Java代码没有编译,我无法弄清楚原因。我把它简化为一组非常简单的代码。任何建议都会非常感激。
角度类定义(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)
}
角度测试用例(用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);
}
}
编译时,我收到此错误:
AngleTest.java:19 incompatible types
found :double
required: com.example.units.Angle
Angle a = Angle.Zero();
^
在我看来,好像Angle.Zero被返回为double,而不是Angle。我尝试添加box / unbox方法,但继续收到相同的错误。再次,非常感谢任何帮助。
答案 0 :(得分:10)
Scala编译器将值类转换为未装箱类型,从而消除了运行时的成本。检查Angle
的已编译类文件,您将看到:
public static double Zero();
所以从Java的角度来看,Angle.Zero返回一个double;它不知道Scala的值类的语义。
Angle自己的方法,例如degrees
,被编译成a)静态扩展方法,它接收未装箱的值(double
)b)实例方法:
public static double degrees$extension(double);
public double degrees();
这意味着后者仍然可以在Java中的Angle
实例上调用:
Angle a = new Angle(0);
Assert.assertEquals(a.degrees(), 0, 1E-9);