空类型
- Java版
class NullUnSafe {
public static void main(String[] args){
System.out.println(getName().length());
}
public static String getName(){
return null;
}
}
上面这段程序会报Exception in thread "main" java.lang.NullPointerException
- Kotlin版
fun getName(): String{
return null
}
fun main(args: Array) {
println(getName().length)
}
因为String是不可空类型(non-null type),编译器会警告Null can not be a value of non-null type String。
修改getName()方法
fun getName(): String{
return "shaoxia"
}
编译通过,而且在这种情况中main方法中不再需要对getName()判空,也就是==if (getName() != null)== 可以省略,还是因为String是不可空类型(non-null type),意味着它的值不可能为null,如果写上判空语句,IDE会提示
Condition 'getName() != null' is always true
那如果要想跟Java一样可以返回null,就得在String后面加上问号"?",把String变为可空类型
class NullUnSafe {
public static String getName() {
return null;
}
public static void main(String[] args) {
String name = getName();
if (name == null) {
System.out.println("name is invalid");
} else {
System.out.println(getName().length());
}
}
}
下面代码跟上面Java等价
fun getName(): String? {
return null
}
fun main(args: Array) {
val name = getName()
if (name == null) {
println("name is invalid")
} else {
println(name.length)
}
}
再进一步利用Kotlin特性
fun getName(): String? {
return null
}
fun main(args: Array) {
val name = getName()
println(name?.length) //①
}
①的意思是,如果name不为null,那么输出name的长度,否则==name?.length==直接返回null
?: 表达式
如果想实现当getName()为null就直接return的需求,则可以
fun main(args: Array) {
val name: String = getName()?:return //①
println(name.length)
}
①语句的意思是,如果getName()为null时就执行后面的return语句,否则就把getName的结果赋值给不可空的String类型变量name
使用可空对象
直接通过'.'使用可选类型对象,编译器是不会通过的,因为它认为对象可能是null,如果能肯定它不为null,要强行使用,可以在'.'之前加上两个叹号'!'
fun main(args: Array) {
val value : String? = "Hello World!"
println(value!!.length)
}
类型转换
Java版
class Parent {
}
class Child extends Parent {
}
class TypeCast {
public static void main(String[] args){
Parent parent = new Child();
//需要显式强转
System.out.println(((Child)parent).getName());
if(parent instanceof Child) {
System.out.println(((Child) parent).getName());
}
}
}
java需要显示的强转,看起来很冗余,kotlin中只要提前告诉了编译器,会自动完成转换,就可以省去类似 ==((Child) parent)== 这样的代码了
fun main(args: Array) {
val parent:Parent = Child()
if (parent is Child){
println(parent.name)
}
}
==String?== 类型智能转换为==String==,不用再写双叹号了。
val string:String? = "Hello"
if (string is String){
println(string.length)
}
类型转换符号 as 与 as?
fun main(args: Array) {
val parent: Parent = Parent()
val child: Child? = parent as? Child
println(child)
val child2: Child? = parent as Child
}
==as?== 是安全的类型转换符,如果转换失败会返回null给child变量,而==as==强制转换失败时会直接抛异常