2011-06-21 11 views
7

necesito para anular el siguiente método Java en una clase Scala:Scala: sobrescribir un método Java genérico que se devuelve un valor nulo

public class Test<T> { 
    public T test(T o, boolean x) { 
     if (x) { 
      return o; 
     } 
     return null; 
    } 
} 

Con el enfoque siguiente (en Scala), el compilador se queja, "Expresión de tipo Null no se ajusta al tipo T espera ":

class Test2[T] extends Test[T] { 
    override def test(o: T, x: Boolean): T = { 
    if (x) { 
     return o 
    } 
    return null 
    } 
} 

también he intentado definir Option[T] como valor de retorno, pero por otra parte, el compilador se queja de que las firmas de los métodos no coincidir.

¿Alguna idea? - ¡Gracias!


Editar:

sugerencia de Daniel trabaja para el problema, ya que originalmente publicada; sin embargo, mi real problema desgracia todavía difiere ligeramente (por tener el parámetro de tipo genérico en el método, no clase, la definición) (lo siento):

Java:

public class Test { 
    public <T> T test(T o, boolean x) { 
     if (x) { 
      return o; 
     } 
     return null; 
    } 
} 

Scala:

class Test2 extends Test { 
    override def test[T >: Null](o: T, x: Boolean): T = { 
    if (x) { 
     return o 
    } 
    return null 
    } 
} 

La compilación falla nuevamente con el error "La expresión del tipo nulo no se corresponde con el tipo esperado T".
(creo que es porque el override no cubre ninguna de las posibilidades - es decir, algo del tipo Nothing se podría pasar a Test.test(..) - Bueno, ¿verdad ;-))

Lo que hace el trabajo es lanzar una RuntimeException en lugar de regresar null como sugirió Ricky; no obstante, agradecería más aportes.

¡Gracias a todos!

Respuesta

12

usted necesita este:

class Test2[T >: Null] extends Test[T] { 

El problema es que no puede haber Nothingnull, y, al ser el subtipo de todo, es un valor válido de T. Por lo tanto, debe especificar Null como límite inferior.

EDITAR

Desafortunadamente, no hay forma alguna de evitar el problema real. En este caso, tendrá que escribir null.asInstanceOf[T] y dejarlo así.

Y, sí, usted puede llamarlo con tipos que no admiten nulos. Prueba de esto, por ejemplo:

object Test3 { 
    val test = new Test(); 
    val x: Int = test.test(5, false); 
} 
+0

Esa es la solución perfecta para el problema tal como se publicó originalmente; sin embargo, tuve que descubrir que el problema real difiere ligeramente. - Marcaré esto como la solución si no hubiera una respuesta más precisa, pero ¿podrías mirar una vez más la pregunta, ahora editada? - Muchas gracias. – robbbert

+0

Gracias, bien hecho. - Ambas soluciones funcionan (la segunda usando '[T]' como parámetro de tipo), aunque todavía no entiendo completamente el problema ... – robbbert

+0

@robbbert Busca información sobre 'Nothing' y' Null' para entenderlo mejor . –

6

T no está restringido, por lo que puede ser cualquier tipo incluyendo Int, Double, Float u otros subtipos de AnyVal que no pueden ser null.

es probable que desee clase Test2[T <: AnyRef] en lugar de la clase Test[T], declarando que es T cualquier tipo que sea AnyRef (básicamente java.lang.Object) o cualquier subtipo de la misma.

En general, intente devolver algo más útil que nulo, o haga una excepción. Puede haber casos en los que deba hacerlo debido a API de terceros, pero si ese no es el caso, vea si hay una forma mejor. null no aparece en el tipo de método, mientras que Option sí, por ejemplo.

+0

Eso es lo que pensaba, pero ' def z [T <: AnyRef]: T = null' aún no compila. – kassens

+0

'clase Test2 [T <: AnyRef] extends Prueba [T]' debería compilar muy bien –

+0

@oxbow_lakes No, no es así, la respuesta de Daniel es correcta. – kassens

0

Ha considerado el uso opción en lugar siguiente trabajo:

class Test{ 
    def test[T] (value:T,flag :Boolean) :Option[T] = { 
    if (flag){ 
     Some(value) 
    }else{ 
     None 
    } 
    } 
} 

que le ayudará a distinguir situaciones como test(null,true) y test(null,false)

+0

Gracias, pero (como se menciona en la pregunta original) es una firma de método diferente a la del método reemplazado. – robbbert

Cuestiones relacionadas