在特征中使用@specialized

时间:2012-04-17 15:58:20

标签: scala specialization autoboxing

我有一个特征和实现,如:

trait Foo[A] {
  def bar[B >: A: Ordering]: Foo[B]
}
class FooImpl[A]( val a: A, val values: List[Foo[A]] ) extends Foo[A] {
  def bar[B >: A] = { /* concrete implementation */}
}  

我想在@specializedA上使用B注释来避免自动装箱。我是否需要在特征和实现中使用它,仅在实现中使用它,或者仅在特征中使用它?

1 个答案:

答案 0 :(得分:3)

REPL和javap一起为我们提供了正确的答案,javap将显示反汇编的java代码。如果将tools.jar添加到REPL类路径中,您将能够执行以下操作:

scala>  trait Foo[@specialized(Int) A] { def doSomething(a:A)}
defined trait Foo

scala>  :javap -p Foo
Compiled from "<console>"
public interface Foo{
    public abstract void doSomething(java.lang.Object);
    public abstract void doSomething$mcI$sp(int);
}

scala> class Hello extends Foo[Int] { def doSomething(a:Int)=println(a)}
defined class Hello

scala>  :javap -p Hello
Compiled from "<console>"
public class Hello extends java.lang.Object implements Foo$mcI$sp,scala.ScalaObject{
    public void doSomething(int);
    public void doSomething$mcI$sp(int);
    public void doSomething(java.lang.Object);
    public Hello();
}

所以现在应该清楚的是,仅在特征级别提供@specialized就足够了:在Foo界面中你显然有两个方法声明。在我看来,那里有一个技巧,但是:

scala>  new Hello
res0: Hello = Hello@7a80747

scala>  res0.doSomething("test")
<console>:11: error: type mismatch;
 found   : java.lang.String("test")
 required: Int

虽然我可以回答你的问题,但仍有一些我无法回答的问题:

  • 为什么这些方法被定义为特征中的公共摘要?
  • 为什么方法doSomething(java.lang.Object)在反汇编类中,但是不能被调用?