2013-08-03 21 views
5

Sto avendo difficoltà a comprendere il messaggio di errore di scalac in questo esempio:utilizzando Java metodo generico da Scala

Bean.java

public class Bean { 
    static public class Attribute<T> { 
    public final String name; 
    public Attribute(String name) {this.name = name;} 
    // equals and hashcode omitted for simplicity 
    } 

    public <T> void set(Attribute<T> attribute, T value) {} 

    public static Attribute<Long> AGE = new Attribute<Long>("age"); 
} 

Test.scala

object Test { 
    def test() { 
    val bean = new Bean(); 
    bean.set(Bean.AGE, 2L); 
    } 
} 

compilando yeilds questo (provato con scalac 2.9.2):

Test.scala:4: error: type mismatch; 
found : Bean.Attribute[java.lang.Long] 
required: Bean.Attribute[Any] 
Note: java.lang.Long <: Any, but Java-defined class Attribute is invariant in type T. 
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10) 
bean.set(Bean.AGE, 2L); 
      ^
one error found 

perché è necessario attributo [Qualsiasi]? Fare stesso in Java funziona bene

grazie

risposta

7

L'errore è dovuto alla mancata corrispondenza tra java.lang.Long e Scala Long.

Bean.AGE è di tipo Bean.Attribute[java.lang.Long]. Quindi il compilatore di scala si aspetta un java.lang.Long come l'altro argomento. Ma stai passando è 2L che è scala.Long e non java.lang.Long. Quindi mostra errore.

Facendo questo funzionerà come previsto:

b.set(Bean.AGE,new java.lang.Long(23)) 

Grazie alla @senia, il sotto è un'alternativa migliore:

bean.set[java.lang.Long](Bean.AGE, 23) 
bean.set(Bean.AGE, 23:java.lang.Long) 
+0

java.util.Long? typo –

+0

@PrinceJohnWesley Oops. Sì. Corretto. Grazie. – Jatin

+3

Non pensi '23: java.lang.Long' sembra un po 'meglio? O anche 'b.set [java.lang.Long] (Bean.AGE, 23)'. – senia