2012-07-30 20 views
7

Me gustaría implementar un método java que use genéricos en scala (2.9.2). Pero estoy fallando ...Scala, no se puede implementar el método genérico de Java

Java método de interfaz:

public <T extends Number> void setAttribute(Key<T> key, Number value); 

código Scala que quieren poner en práctica ese método:

def setAttribute[T <: Number](key: Key[T], value: Number) = { 
    setAttributeLocal(key, value) } 

private def setAttributeLocal[T](key: Key[T], value: T) = { 
    val stringValue = ConvertUtils.convert(value, classOf[String]).asInstanceOf[String] 
    session = session + (key.getValue() -> stringValue) 
} 

clave parece:

public class Key<T> 

Pero esto no compila.

[error] found : mypackage.Key[T] 
[error] required: mypackage.Key[java.lang.Number] 
[error] Note: T <: java.lang.Number, but Java-defined class Key is invariant in type T. 
[error] You may wish to investigate a wildcard type such as `_ <: java.lang.Number`. (SLS 3.2.10) 
[error]  setAttributeLocal(key, value) 

No puedo entender cuál es el problema. Alguna sugerencia/idea?

greez GarfieldKlon

+1

Tendremos que saber cómo se ve 'Key'. Porque si uso 'clave de interfaz pública ', el código anterior compila bien. –

+0

@GarfieldKlon ¿Con qué versión de scala estás trabajando? –

+0

@ 0__ ¿bajo qué versión compila? –

Respuesta

4

Parece que el compilador es infeliz con su llamada a setAttributeLocal. setAttributeLocal requiere un Key[Number], pero está proporcionando un Key[_ <: T]. En Java-Land, esto significa que está intentando pasar un Key<? extends Number> como Key<Number>.

La sugerencia es tener setAttributeLocal aceptar Key<? extends Number> o Key[_ <: Number], dependiendo de si está definido por Java o Scala.

+0

@GarfieldKlon Tuve que leer esto un par de veces ... Creo que lo que sugiere Ben es que si te centras en arreglar 'setAttribute' entonces quizás estés viendo algo incorrecto. El error que describió es un problema de tipo con 'setLocalAttribute', no' setAttribute'. ¿A qué se parece tu definición de 'setLocalAttribute'? –

+0

@Richard - bien, que explica por qué no podía reproducir este –

+0

Finalmente añadimos esta solución: 'privada def setAttributeLocal [T] (tecla: Tecla [T], value: Object)' – GarfieldKlon

1

Algo se ve un poco raro aquí.

Ha intentado:

def setAttribute[T <: Number](key: Key[T], value: T) = 
    setAttributeLocal(key, value) 

Parece extraño/malo para preservar el tipo T para la llave, pero no lo uso en el valor. Supongo que ahí es donde estás obteniendo un error invariable. Está intentando asignar el valor del tipo Number a una clave del tipo T y el compilador no está seguro si no puede pasar Number para T (aunque sabe que puede pasar T para Number).

¿Podemos ver más código?

+0

Eso no es una opción, porque no es una anulación – GarfieldKlon

+0

Existen limitaciones en las interfaces de tipos de Java y Scala. Lo que estás haciendo en Java es escribir poco sólido, por lo que Scala no lo permite. Si desea continuar usando ese tipo de magia, entonces tendrá que seguir con el sistema de tipos de Java, lo siento. – jsuereth

1

Como @jsuereth ya se ha señalado, existe una discrepancia entre las firmas de setAttribute y setAttributeLocal, a saber, que el primero acepta un Key[T <: Number] pero que fije el valor que va con la clave para ser un Number exactamente, mientras que el último es más flexible y permite que la clave y el valor sean T <: Number. Esto parece bastante extraño y es posible que desee reconsiderar esa decisión. También lleva al problema explicado por @Ben Schulz.

En cualquier caso, el compilador (2.9.1) está feliz con la siguiente configuración:

MyI.java:

public interface MyI { 
    public <T extends Number> void setAttribute(Key<T> key, Number value); 
} 

Key.java:

public interface Key<T> { 
} 

Test.scala:

object Test extends App { 
    def setAttribute[T <: Number](key: Key[T], value: Number) = { 
    setAttributeLocal(key, value) } 

    private def setAttributeLocal[T](key: Key[T], value: Number) = { 
    /* Notice that value is now also of type Number. */ 
    } 
} 
Cuestiones relacionadas