官方文檔: http://kotlinlang.org/docs/reference/java-interop.html
繼續(xù)上一章
5.Java空安全和平臺類型(Null-Safety and Platform Type)
在Java中任何引用都可能是null,這使Kotlin要求Java對象嚴格空安全是不現(xiàn)實的!
Java聲明的類型在Kotlin中會被特別對待,稱為平臺類型(platform types)!
kotlin對平臺類型的空檢查(Null-checks)會放寬,因此它們在kotlin中的安全性與在Java中一樣!
示例:
val list = ArrayList<String>() // 非空(構(gòu)造函數(shù)結(jié)果)
list.add("Item")
val size = list.size() // 非空(原生 int)
val item = list[0] // 推斷為平臺類型(普通Java對象)
當調(diào)用平臺類型的方法時,Kotlin不會在編譯時檢查可空性null錯誤,
但在運行時調(diào)用可能報錯,出現(xiàn)空指針異常NullPointerException或者Kotlin斷言阻止null傳播!
item.substring(1) // 允許,如果item == null,可能會拋出異常
平臺類型(platform types)是不可標示(non-denotable),意味著不能在kotlin語言中明確地寫下指定!
當把平臺類型值賦值給Kotlin變量時,可以依賴類型推斷,或者選擇期望的類型(可空null或非空null類型均可):
val nullable: String? = item // 允許可空(null)
val notNull: String = item // 允許非空(notNull),運行時可能失敗(null)
如果選擇非空類型(kotlin),編譯器在賦值時會觸發(fā)斷言assertion,防止Kotlin的非空變量保存空值(null)!
當把平臺值傳遞給期待非空的Kotlin函數(shù)時,也會觸發(fā)斷言!
總而言之,編譯器盡力阻止空值(null)通過程序傳播(鑒于泛型原因,有時不能完全消除)
1.平臺類型表示法(Notation for Platform Type)
如上所述,平臺類型不能在程序中顯式表示,因此在kotlin語言中沒有相應(yīng)語法!
但是有時編譯器或IDE要在錯誤/參數(shù)信息中顯示平臺類型,所以可用助記符標記:
T! 表示T 或者 T?
(Mutable)Collection<T>! 表示T的Java集合 可變或不可變, 可空或不可空
Array<(out) T>! 表示T(或T子類)的Java數(shù)組 可空或者不可空
2.可空性注解(Nullability annotation)
具有可空性注解的Java類型并不表示為平臺類型,而表示為實際可空或非空的Kotlin類型,
編譯器支持多種可空性注解:
JetBrains (@Nullable and @NotNull from the org.jetbrains.annotations package)
Android (com.android.annotations and android.support.annotations)
JSR-305 (javax.annotation)
FindBugs (edu.umd.cs.findbugs.annotations)
Eclipse (org.eclipse.jdt.annotation)
Lombok (lombok.NonNull).
6.Java類型映射(Mapped type)
Kotlin會特殊處理部分的Java類型,映射到相應(yīng)的Kotlin類型,映射只發(fā)生在編譯期間,運行時表示保持不變!
1.Java基本類型映射到相應(yīng)Kotlin類型:
Java類型 Kotlin類型
byte kotlin.Byte
short kotlin.Short
int kotlin.Int
long kotlin.Long
char kotlin.Char
float kotlin.Float
double kotlin.Double
boolean kotlin.Boolean
2.Java包裝類(基本類型)映射成可空Kotlin類:
Java類型 Kotlin類型
java.lang.Byte kotlin.Byte?
java.lang.Short kotlin.Short?
java.lang.Integer kotlin.Int?
java.lang.Long kotlin.Long?
java.lang.Character kotlin.Char?
java.lang.Float kotlin.Float?
java.lang.Double kotlin.Double?
java.lang.Boolean kotlin.Boolean?
注意: 當java包裝類作為類型參數(shù),會被映射成平臺類型,例如,List<java.lang.Integer>在Kotlin中會變成List<kotlin.Int!>
3.Java一些非基本類型也會映射:
Java類型 Kotlin類型
java.lang.Object kotlin.Any!
java.lang.Cloneable kotlin.Cloneable!
java.lang.Comparable kotlin.Comparable!
java.lang.Enum kotlin.Enum!
java.lang.Annotation kotlin.Annotation!
java.lang.Deprecated kotlin.Deprecated!
java.lang.CharSequence kotlin.CharSequence!
java.lang.String kotlin.String!
java.lang.Number kotlin.Number!
java.lang.Throwable kotlin.Throwable!
4.Java集合類型在Kotlin中既能只讀,也能可變,因此有以下映射(Kotlin集合在kotlin.collections包)
Java類型 Kotlin只讀類型 Kotlin可變類型 平臺類型(platform type)
Iterator<T> Iterator<T> MutableIterator<T> (Mutable)Iterator<T>!
Iterable<T> Iterable<T> MutableIterable<T> (Mutable)Iterable<T>!
Collection<T> Collection<T> MutableCollection<T> (Mutable)Collection<T>!
Set<T> Set<T> MutableSet<T> (Mutable)Set<T>!
List<T> List<T> MutableList<T> (Mutable)List<T>!
ListIterator<T> ListIterator<T> MutableListIterator<T> (Mutable)ListIterator<T>!
Map<K, V> Map<K, V> MutableMap<K, V> (Mutable)Map<K, V>!
Map.Entry<K, V> Map.Entry<K, V> MutableMap.MutableEntry<K,V> (Mutable)Map.(Mutable)Entry<K, V>!
5.Java數(shù)組在Kotlin中映射:
Java類型 Kotlin類型
int[] kotlin.IntArray!
String[] kotlin.Array<(out) String>!
7.在Kotlin中的Java泛型(Java generics in Kotlin)
Kotlin泛型與Java有些不同,當在Kotlin中使用Java泛型時,會執(zhí)行一些轉(zhuǎn)換:
1.Java通配符(wildcard)轉(zhuǎn)換成類型投影(type projection)
Foo<? extends Bar> 轉(zhuǎn)換成 Foo<out Bar!>!
Foo<? super Bar> 轉(zhuǎn)換成 Foo<in Bar!>!
2.Java原始類型轉(zhuǎn)換成星投影(star projection)
List 轉(zhuǎn)換成 List<*>! 即List<out Any?>!
和Java一樣,Kotlin在運行時不保留泛型,即對象不會把類型參數(shù)傳遞到構(gòu)造器!
即不能區(qū)分ArrayList<Integer>()和ArrayList<Character>()
這使得is操作符不能檢測泛型,Kotlin只允許is檢測星投影的泛型類型:
if (a is List<Int>) // 錯誤: 無法檢查a是否為Int列表
if (a is List<*>) // OK: 不保證列表內(nèi)容
簡書:http://www.reibang.com/p/bc65be16a489
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/75093931
GitHub博客:http://lioil.win/2017/07/13/Kotlin-javaInKotlin2.html
Coding博客:http://c.lioil.win/2017/07/13/Kotlin-javaInKotlin2.html