在Java中使用Scala 2.10.1值类型

时间:2013-03-31 17:38:14

标签: java scala compiler-errors value-type

我将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方法,但继续收到相同的错误。再次,非常感谢任何帮助。

1 个答案:

答案 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);