2017-01-21 58 views
-1

我一直在定義Scala類中的私有和受保護的方法,但是當編譯爲java字節碼時,它們只會消失,所有方法都會公開!所以當從java調用時,我可以調用其中的任何一個。我說的是對的嗎?如果是這樣,在不久的將來會用新的編譯器改變這個嗎?Java和Scala與私有修飾符的集成

+0

請有你正在做的代碼段。 – marios

回答

0

有時訪問被擴大,沒有任何名稱混亂或混淆。

在這裏,你可能期望的實現,以顯示默認包訪問:

scala> :pa 
// Entering paste mode (ctrl-D to finish) 

package p { class C { private[p] def c = 42 }} 

// Exiting paste mode, now interpreting. 


scala> :javap p.C 
[snip] 
    public int c(); 

一個特殊的訪問,這裏提供了模式匹配:

scala> case class C(private val c: Int) 
defined class C 

scala> :javap -pv C 
[snip] 
    private final int c; 
    descriptor: I 
    flags: ACC_PRIVATE, ACC_FINAL 

    public int c$access$0(); 

這不是靠一個好主意用於一般互操作目的的任何此類實現細節。但是,Scala承諾在諸如2.12.x之類的發行版系列中實現二進制兼容性。任何使用2.12.1編譯的代碼都必須與使用2.12.2編譯的新代碼鏈接。

1

我一直在定義Scala類的私有和受保護的方法,但是當編譯成java字節碼時,它們只是消失,所有的方法都變成公共的!

Scala的訪問修飾符語義不映射到JVM的訪問修飾符語義。任何翻譯它們的方式都必須是近似的。有時,最接近的近似值是public

就是這樣。只要看看斯卡拉母語進行比較,其編譯爲本地二進制機器碼:所有訪問修飾符,並所有類型完全走了,因爲根本沒有辦法來表示他們在本機二進制機器碼。即使是Java,也無法在JVM字節碼中正確表示(例如Java有泛型,但JVM無法表示它們)。

所以當從java調用時,我可以調用它們中的任何一個。我說的是對的嗎?

是的。當您使用Java與Scala代碼進行交互時,您將繞過對Scala編譯器的任何檢查。這是沒有辦法的。

如果是這樣,那麼在不久的將來會改變一個新的編譯器?

不需要。它需要更改JVM規範以允許語言指定其自己的訪問修飾符語義。我沒有看到發生。

+0

謝謝您的意見!以下是我在談論的一個例子: 類Person(){ 私人高清的run(){ } 保護的高清行走(英里的:int){ } } 在這種情況下,當使用Java或Scala編譯的類(.class)時,這兩種方法(walk和run)都會成爲公有的方法。我知道同樣的情況發生在泛型上,它們不是虛擬機的一個特性部分,但我個人發現修飾符比泛型更重要,沒有泛型,甚至可以以舊的方式執行 – mingo

+0

即使是Java的'private'修飾符類(僅與嵌套類型相關)實際上並不存儲在通常的訪問修飾符字段中。它存儲在一個專用於內部類的特殊屬性中,由Reflection支持,而JVM本身不強制執行「私有」訪問級別...... – Holger