2011-08-31 161 views
12

Scala定义了一个AnyRef类,它在编译之后被解释为Java的Object类。但是,从语言的角度来看,AnyRef类并不完全等同于Object,因为它引入了几个新方法,如eq(),它采用AnyRef并返回布尔值并比较标识的引用如何从Scala调用Java接口的T eq(Object)方法?

如果在Java类本身定义了不同的结果类型和该类实现也具有这种方法的接口的当量()方法:

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

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

然后其当量方法变得不可访问到Scala代码如果经由接口参考称为

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 

Scala知道的eq方法是来自AnyRef类的eq方法,该方法被“粘贴”到来自Java的接口I,而没有使用该方法,但使用自己的eq()方法使用不同的结果类型。 我可以解释这种行为,但如果我不得不调用此Java eq()方法而无法修改Java第三方库的代码,则无法解决真实任务。 即我说的是Liferay及其动态查询API和名为com.liferay.portal.kernel.dao.orm.Property的接口。它有一个eq()方法,接受Object并返回Criterion。此代码不会在Scala中编译:

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

因为eq不会被正确解释。 只需要提一下,Property类具有以DynamicQuery作为参数的eq()方法的另一个重载。这个过载可以从Scala访问。

你知道有什么方法可以从Scala调用Java接口的eq(Object)方法吗?使用

的Scala版本是2.8.1

+0

你尝试'a.eq(b.asInstanceOf [对象])':

FWIW,你可以做到吗? –

+0

适用于我,没有编译错误,并调用正确的方法。 – Lex

+0

不幸的是,它并没有帮助。我更新了描述,还有一个界面在这里扮演角色 – kyrel

回答

5

有趣的问题:我从来没有见过这个。我不知道如何在Scala中解决它,或者即使它可能。然而,在这种情况下,你可以做的最好的事情就是用Java创建一个包装器。例如:

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

然后,您只需拨打Eq.eq(x, y)而不是x.eq(y)

+0

是的,如果没有直接的Scala方式,它真的会结束。我会稍微等待其他想法,并将其标记为正确答案。谢谢! – kyrel

1

我不能抓住一切,因为它看起来太明显了。如果(i:I).eq(o): String不起作用,但A.eq(o): String起作用,为什么这不起作用?

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

所以

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

+0

'Property'是一个接口,而不是一个类(参见http://docs.liferay.com/portal/5.1/javadocs/portal-kernel/com/liferay/portal/kernel/dao/orm/Property.java.html ) –

+0

@Alexey Romanov,是在运行时生成的属性的具体子类? – huynhjl

+0

我不知道,因为我不使用Liferay ... –

3

您可以通过反射做(与任何具体的类实例化以后,如com.liferay.portal.dao.orm.hibernate.PropertyImpl更换XYZ),但我不知道这是否就是你”因为它很丑,所以想要。

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

类型的丑陋,但比我目前的黑客更好,谢谢! – kyrel

+0

我的上帝。一个人必须做这样的事情很可悲。但它的工作。 – goroncy

相关问题