REPLは、分解されたJavaコードを表示するjavapとともに、正しい答えを持っています。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インターフェースでは、明らかに2つのメソッド宣言があります。しかし、そこではトリックが行われているように見えます。
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)が逆アセンブルされたクラスにあるのに、呼び出すことができないのはなぜですか?