REPL имеет правильный ответ для нас вместе с 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 = [email protected]
scala> res0.doSomething("test")
<console>:11: error: type mismatch;
found : java.lang.String("test")
required: Int
В то время как я могу ответить на ваш вопрос, есть некоторые вопросы, которые я не могу ответить:
- Почему методы определены как публичный аннотация в признаке?
- Почему метод doSomething (java.lang.Object) существует в дизассемблированном классе, но не может быть вызван?
Как вы ожидаете, что специализация будет работать, если вы используете «Список», который не является специализированным? Тогда вы не можете избежать бокса. –
Извините, ошибка в упрощении кода для публикации. Класс содержит экземпляр A (который я не хочу использовать autobox и 'List [Foo [A]]'. – paradigmatic
Хорошо, но 'Ordering' также не является специализированным. –