2011-08-31 28 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