2011-08-31 4 views
12

Scala definisce una classe AnyRef che è dopo la compilazione interpretato un po 'come classe Object di Java. La classe AnyRef, tuttavia, non è esattamente equivalente a Object dal punto di vista della lingua, perché introduce diversi nuovi metodi, come eq(), che accetta AnyRef e restituisce Boolean e confronta i riferimenti per l'identitàCome chiamare il metodo T eq (Object) dell'interfaccia Java da Scala?

Se c'è una classe in Java che si definisce il metodo eq() con un diverso tipo di risultato e un'interfaccia che questa classe implementa anche avendo questo metodo:

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

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

quindi il suo metodo eq diventa inaccessibile al codice Scala se chiamato tramite interfaccia di riferimento

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 

Il metodo eq Scala conosce qui è il metodo eq dalla classe AnyRef essere "incollato" per interfacciare I, che è venuto da Java senza quel metodo, ma con un metodo eq() della propria con un diverso tipo di risultato. posso spiegare questo comportamento, ma non può risolvere il compito di vita reale quando devo chiamare il metodo questo Java eq() senza un possiblity per modificare il codice della libreria di terze parti Java. Vale a dire che sto parlando di Liferay e le sue API Query dinamica e l'interfaccia denominata com.liferay.portal.kernel.dao.orm.Property. Ha un metodo eq() che accetta Object e restituisce Criterion. Questo codice non verrà compilato in Scala:

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

perché eq non verrà interpretato correttamente. Solo per citare, la classe Property ha un altro overload del metodo eq() che prende come parametro DynamicQuery. Questo sovraccarico è accessibile da Scala.

Sapete di un modo per chiamare quel metodo eq (Object) di interfaccia Java da Scala?

versione Scala utilizzata è 2.8.1

+0

Hai provato 'A.EQ (b.asInstanceOf [Object])'? –

+0

Funziona per me, nessun errore di compilazione e viene chiamato il metodo corretto. – Lex

+0

Sfortunatamente non aiuta.Ho aggiornato la descrizione, c'è anche un'interfaccia che gioca un ruolo qui – kyrel

risposta

5

problema interessante: non avevo mai visto questo prima. Non so come risolverlo in Scala, o anche se è possibile a tutti. In tali situazioni, tuttavia, il meglio che puoi fare è creare un wrapper in Java. Per esempio:

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

È poi basta chiamare Eq.eq(x, y) invece di x.eq(y).

+0

Sì, finirà davvero così se non c'è un modo Scala diretto. Aspetterò un po 'per altre idee e segnalo come risposta corretta. Grazie! – kyrel

1

Non devo afferrare tutto perché sembra troppo ovvio. Se (i:I).eq(o): String non funziona ma funziona A.eq(o): String, perché questo non funziona?

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

Così

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

(sostituire XYZ con qualunque classe concreta è istanziare come com.liferay.portal.dao.orm.hibernate.PropertyImpl)

+0

'Proprietà' è un'interfaccia, non una classe (consultare http://docs.liferay.com/portal/5.1/javadocs/portal-kernel/com/liferay/portal/kernel/dao/orm/Property.java.html) –

+0

@Alexey Romanov, è la sottoclasse concreta della proprietà generata in fase di runtime? – huynhjl

+0

Non lo so, dato che non uso Liferay ... –

3

È possibile farlo attraverso la riflessione, ma non so se questo è ciò che si' Voglio perché è un po 'brutto.

FWIW, è possibile farlo da:

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

Un po 'brutto, ma meglio del mio attuale hack, grazie! – kyrel

+0

Mio Dio. È triste che uno debba fare queste cose. Ma funziona. – goroncy

Problemi correlati