2011-08-31 7 views
12

Scala define una clase AnyRef que luego de la compilación se interpreta como la clase Object de Java. La clase AnyRef, sin embargo, no es exactamente equivalente a Object desde el punto de vista del lenguaje, ya que introduce varios métodos nuevos, como eq(), que toma AnyRef y devuelve Boolean y compara referencias para la identidadCómo llamar al método T eq (Object) de la interfaz Java desde Scala?

Si hay una clase en Java que a su vez define el método eq() con un tipo de resultado diferente y una interfaz que esta clase implementa teniendo también este método:

public interface I { 
    String eq(Object that); 
} 

public class A implements I { 
    public String eq(Object that) {return "";} 
} 

entonces su método eq vuelve inaccesible a código Scala si se llama a través de referencia de interfaz

val i: I = new A 
val a = new A 
val b = Some(1)   //whatever actually 
val s1: String = a.eq(b) //compiles OK 
val s2: String = i.eq(b) //compilation error 

El método eq que Scala conoce aquí es el método eq de la clase AnyRef que está "pegado" a la interfaz I que proviene de Java sin ese método, pero con un método eq() propio con un tipo de resultado diferente. Puedo explicar este comportamiento, pero no puedo resolver la tarea de la vida real cuando tengo que llamar a este método Java eq() sin la posibilidad de modificar el código de la biblioteca Java de terceros. A saber, estoy hablando de Liferay y su Dynamic Query API y la interfaz llamada com.liferay.portal.kernel.dao.orm.Property. Tiene un método eq() que toma Object y Return Criterion. Este código no se compilará en Scala:

val query = DynamicQueryFactoryUtil.forClass(classOf[BookmarksEntry]) 
.add(PropertyFactoryUtil.forName("folderId").eq(new Long(folderId))) 

porque eq no se interpretará correctamente. Solo para mencionar, la clase Propiedad tiene otra sobrecarga del método eq() que toma DynamicQuery como parámetro. Esta sobrecarga es accesible desde Scala.

¿Conoces alguna forma de llamar a ese método eq (Object) de la interfaz Java desde Scala?

versión 2.8.1 Scala utilizado es

+0

¿Usted intentó 'A.EQ (b.asInstanceOf [Objeto])'? –

+0

Funciona para mí, no hay error de compilación, y se llama al método correcto. – Lex

+0

Desafortunadamente no ayuda.He actualizado la descripción, también hay una interfaz desempeñando un papel aquí – kyrel

Respuesta

5

problema interesante: No había visto esto antes. No sé cómo resolverlo en Scala, o incluso si es posible en absoluto. En tales situaciones, sin embargo, lo mejor que puede hacer es crear un contenedor en Java. Por ejemplo:

public class Eq { 
    static public String eq(I obj, Object that) { 
     return obj.eq(that); 
} 

A continuación, sólo llama Eq.eq(x, y) en lugar de x.eq(y).

+0

Sí, realmente terminará así si no hay una forma directa de Scala. Esperaré un poco por otras ideas y marcaré esto como la respuesta correcta. ¡Gracias! – kyrel

1

No debo entender todo porque parece demasiado obvio. Si (i:I).eq(o): String no funciona pero A.eq(o): String funciona, ¿por qué no funciona?

scala> i.asInstanceOf[A].eq(b) 
res2: java.lang.String = str 

Así

val query = DynamicQueryFactoryUtil.forClass(classOf[BookmarksEntry]) 
    .add(PropertyFactoryUtil.forName("folderId").asInstanceOf[XYZ] 
    .eq(new Long(folderId))) 

(sustituir XYZ con cualquier clase concreta está instanciado como com.liferay.portal.dao.orm.hibernate.PropertyImpl)

+0

'Propiedad' es una interfaz, no una clase (ver http://docs.liferay.com/portal/5.1/javadocs/portal-kernel/com/liferay/portal/kernel/dao/orm/Property.java.html) –

+0

@Alexey Romanov, ¿es la subclase concreta de Propiedad generada en tiempo de ejecución? – huynhjl

+0

No lo sé, ya que no utilizo Liferay ... –

3

Puede hacerlo a través de la reflexión, pero no sé si eso es lo que' quiero porque es feo.

Fwiw, puede hacerlo a través de:

i.getClass().getMethod("eq", classOf[Object]).invoke(i, "a").asInstanceOf[String] 
+0

Algo feo, pero mejor que mi hack actual, ¡gracias! – kyrel

+0

Dios mío. Es triste que uno tenga que hacer tales cosas. Pero funciona. – goroncy

Cuestiones relacionadas