VisibleDomainDemo
一個討論Kotlin和Java可見域的demo
因本群一個小伙伴的問題,在解決的過程中發(fā)現(xiàn)了這些東西…kotlin的internal模塊級私有和java的默認包級私有,在互相調(diào)用的過程中,會有哪些問題呢?看完本demo你就了解了,如有錯誤請糾正
測試前提:
lib類庫里的Java類有默認可見域的接口(包級私有)和public可見域的接口實現(xiàn)類
lib類庫里的kotlin類有internal可見域的接口和public可見域的接口實現(xiàn)類
測試內(nèi)容一:
測試lib類庫里的java類
假設lib類庫里包級私有接口名為IA,里面有包級私有的內(nèi)部接口IAInner
假設IA的public可見域的實現(xiàn)類名為AImpl,里面有包級私有的內(nèi)部接口AImplInner
測試步驟一:
1.app類中的Java類能否引用lib類庫里AImpl繼承下來的IAInner和AImpl自己的AImplInner
2.app類中的Kotlin類能否引用lib類庫里AImpl繼承下來的IAInner和AImpl自己的AImplInner
3.app類中的Java類能否改變lib類庫里IA和IAInner的可見域和AImpl自己的AImplInner可見域
4.app類中的Kotlin類能否改變lib類庫里IA和IAInner的可見域和AImpl自己的AImplInner可見域
測試內(nèi)容二:
測試lib類庫里的kotlin類
假設lib類庫里模塊級私有接口名為IA,里面有模塊級私有的內(nèi)部接口IAInner
假設IA的public可見域(kotlin默認)的實現(xiàn)類名為AImpl,里面有模塊級私有的內(nèi)部接口AImplInner
測試步驟二:
5.app類中的Java類能否引用lib類庫里的IA和IAInner和AImpl自己的AImplInner
6.app類中的Kotlin類能否引用lib類庫里AImpl繼承下來的IAInner和AImpl自己的AImplInner
7.app類中的Java類能否改變lib類庫里IA和IAInner的可見域和AImpl自己的AImplInner可見域
8.app類中的Kotlin類能否改變lib類庫里IA和IAInner的可見域和AImpl自己的AImplInner可見域
測試結果:
詳見各個測試類
測試總結:
1.java的app調(diào)用java的lib類庫,即使java的lib類庫有類(或者接口)有內(nèi)部類(或者有內(nèi)部接口)為包級私有,只要這些類(或者接口)有子類(或者實現(xiàn)類),并且這些子類(或者實現(xiàn)類)是public的,那么這些子類(或者實現(xiàn)類)是能暴露父類(或者父接口)的包級私有內(nèi)部類(或者包級私有內(nèi)部接口)的可見性的(這是錯誤的,不應該暴露)
2.java的app調(diào)用java的lib類庫,即使java的lib類庫有類(或者接口)有內(nèi)部類(或者有內(nèi)部接口)為包級私有,只要在app層創(chuàng)建這些包級私有類(或者接口)的同包名類(或者接口),就可以訪問lib類庫里的這些包級私有類(或者接口)
3.java的app調(diào)用kotlin的lib類庫,即使kotlin的lib類庫有類(或接口)為internal模塊級私有權限,但是對java來說就和public一樣可見要解決這個問題可以參考這篇文章(http://ice1000.org/2017/11/12/InternalFucksJava/#%E6%96%B9%E6%B3%95%E4%B8%80)不過,kotlin函數(shù)可以用這篇文章的辦法解決,但是類卻不可以,因為@file:JvmName只能將這個kt文件命名為該類,卻不能改變指定類的名字
4.kotlin的app調(diào)用java的lib類庫,會嚴格遵守可見性,不會因為繼承(或者實現(xiàn))了父類(或父接口)而把父類(或者副接口)的內(nèi)部包級私有類(或者內(nèi)部包級私有接口)暴露,所以也不會像java的app那樣能調(diào)用父類(或副接口)的內(nèi)部包級私有類(或內(nèi)部包級私有接口)
5.kotlin的app調(diào)用kotlin的lib類庫,如果kotlin的lib類庫有類(或接口)為internal模塊級私有權限,那么kotlin是無法調(diào)用的