在Java中使用Scala 2.10.1值类型
我正在将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方法,但继续收到相同的错误。 再次,任何帮助将不胜感激。
Scala编译器将值类转换为未装箱类型,从而消除了运行时的成本。 检查已编译的类文件的Angle
,你会看到:
public static double Zero();
所以从Java的角度来看,Angle.Zero返回一个double; 它不知道Scala的值类的语义。
Angle自己的方法,如degrees
,被编译成a)一个静态扩展方法,它接受unboxed值( 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);