2012-03-22 64 views
1

編譯Scala代碼似乎有一個問題,該代碼在Java 7 JVM和Scala中使用較舊的(Java 6)JDBC DataSource驅動程序。在Scala中使用Java 7 CommonDataSource

在Java 7中,Oracle爲CommonDataSource接口添加了一種新方法Logger getParentLogger()。使用Java 6構建的舊類實現CommonDataSource不會實現此方法(例如PGConnectionPoolDataSourceSQLServerDataSource)。當代碼用Scala編譯器編譯時,它會抱怨具體類沒有實現抽象方法getParentLogger

我不知道這是否與Java編譯器發生,但我懷疑不是,因爲它應該已被單元測試捕獲。

我相信,任何添加新方法聲明的接口都會出現此問題。

對於這個問題,Scala是否有任何解決方法?是唯一能夠恢復到JDK 6的解決方案嗎?我沒有SQL Server驅動程序的源代碼,所以我不能自己修復這個問題(我知道開放源代碼沒有這個問題,但我被迫使用該驅動程序出於其他原因)。

+0

什麼代碼是抱怨?你是否試圖實例化一個'SQLServerDataSource',擴展它,或者你在做別的什麼? – leedm777 2012-03-22 20:57:27

+0

'new SQLServerDataSource {...}'試圖將它擴展爲一個匿名的子類(設置大括號內的主機等東西)。我也嘗試創建一個實例,然後初始化屬性**,它工作**。 – Ralph 2012-03-23 10:51:54

回答

1

在您的匿名子類中實現缺少的方法。

new SQLServerDataSource { 
    def getParentLogger: Logger = null 
    // other stuff 
} 

這一點古怪實際上是JVM的一個很好的功能,允許向後兼容的一定程度,當你添加方法接口。 我相信你會看到與Scala一樣的Java行爲。 看起來像Java 在這些情況下更容忍缺少方法定義。我不完全確定爲什麼,但我的猜測是,這可能與如何實施特質有關。

向接口添加方法是一種變化,即binary compatibly but source incompatible。這就是爲什麼您可以直接創建SQLServerDataSource的實例。如果您嘗試在該實例上調用getParentLogger,則編譯器將允許您執行此操作,但運行時您將得到。

爲了實例化你的匿名內部類,它必須實現所有的抽象方法才能成爲一個具體的類。由於SQLServerDataSource不提供getParentLogger的實現,所以您必須在您的子類中。

+0

爲什麼在沒有具體方法定義的情況下,Java在相同的情況下工作? Java更容忍在預編譯類中缺少抽象方法嗎? – Ralph 2012-03-23 13:30:53

+0

我編輯了我的答案以提供更多詳細信息。這基本上是二進制兼容性和源代碼兼容性的區別。 – leedm777 2012-03-23 13:48:26