Il REPL ha la risposta giusta per noi, insieme a javap, che mostrerà il codice java disassemblato. Se si aggiunge tools.jar al classpath REPL, si sarà in grado di fare cose interessanti come la seguente:
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();
}
Così ora dovrebbe essere chiaro a voi che fornire il @specialized solo a livello caratteristica è sufficiente: nell'interfaccia Foo hai chiaramente due dichiarazioni di metodo. Sembra a me che un trucco sta succedendo lì, però:
scala> new Hello
res0: Hello = [email protected]
scala> res0.doSomething("test")
<console>:11: error: type mismatch;
found : java.lang.String("test")
required: Int
Mentre posso rispondere alla tua domanda, ci sono alcune domande che non posso rispondere:
- Perché i metodi sono definiti come astratto pubblico nel tratto?
- Perché il metodo doSomething (java.lang.Object) è presente nella classe disassemblata, ma non può essere chiamato?
Come ti aspetti che la specializzazione funzioni se stai utilizzando un 'Elenco' che non è specializzato in se stesso? Non si può quindi evitare la boxe. –
Siamo spiacenti, errore nel semplificare il codice per la pubblicazione. La classe contiene un'istanza di A (che non desidero autobox e un 'List [Foo [A]]'. – paradigmatic
Ok, ma 'Ordering' non è specializzato –