目录
先抛出个结论:
? ?:的使用方法
? ?:结论:
!!的使用方法
!!总结:
先抛出个结论:
? 问号修饰,两种使用方式
- ?放在类名后面修饰表示对象可空;
- ?放在对象后修饰,则代表如果对象为空,则不执行后面的代码
?: 问号冒号修饰符
- ?:放在对象后面,代表如果对象为空,执行 ?: 后面的代码
!! 叹号修饰符
- !! 放在对象后面,表示即使对象为空我也要往下执行,可能会抛出空指针异常
//用于测试的对象返回器
class ObjectReturner<T> {
var r : Boolean = false
var obj : T? = null
constructor(r : Boolean , obj: T){
this.r = r
this.obj = obj
}
fun getObjMethod() : T?{
return obj.takeIf { r } //如果r为true返回obj,如果r为false返回null
}
}
data class Student(val name : String , val age : Int)
? ?:的使用方法
var obj4: Student? = ObjectReturner(false , stu1).getObjMethod()
println("obj4.name = ${obj4?.name}")
obj4.run {
println(this)
} ?: println("怎么返回空了呢")
上面的方法,永远不会执行到 ?: 后面的语句因为getObjMethod()即使返回空也执行到了run方法,最终打印null。
println("obj4.name = ${obj4?.name}")如果这里不加问号直接访问obj4的属性是编译不过的,因为obj4可能为null。
而使用obj4.run可以不加问号是可以编译过的(无语了)
分析这里的原因要看kotlin翻译成java后的代码
obj4.run{println(this)}的反编译结果
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
String var5 = "obj4.name = " + (obj4 != null ? obj4.getName() : null); //看这里
System.out.println(var5); //这里是关键
int var7 = false;
System.out.println(obj4);
obj4.run之所以不用加?就可以编译通过,就是因为翻译成java后obj4.run压根就没有使用obj4的任何方法或者属性。因为run方法也不是obj4的成员方法,所以可以正常编译通过,执行也不会报异常。
obj4?.run{println(this)}的反编译结果
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
String var5 = "obj4.name = " + (obj4 != null ? obj4.getName() : null);//看这里
System.out.println(var5);
if (obj4 != null) {//看这里 是 ? 翻译后的java代码
int var7 = false;
System.out.println(obj4);
} else { //看这里 是 ?: 翻译后的java代码
var5 = "怎么返回空了呢";
System.out.println(var5);
}
当加上了?以后调用run方法,翻译后的结果自动加上了 obj4 != null 的判断。
? ?:结论:
- 我们在调用方法或者使用属性之前加上了?,翻译后的java代码其实就是一个if判断,而使用 ?:则翻译后的java代码其实就是加了一个else
!!的使用方法
如果一个对象是用 ? 修饰的,表示此对象可能为空,这时如果你在使用这个对象的时候必须在对象后面加上 "?" 或者 "!!"否则是编译不过的
- 加上 "?" 上文已经介绍过了,java翻译后会自动加上if判断,如果为空则不执行。
- 加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常
var obj4: Student? = ObjectReturner(false , stu1).getObjMethod()
println("obj4.name = ${obj4!!.name}")
翻译后的java代码:
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
StringBuilder var11 = (new StringBuilder()).append("obj4.name = ");
Intrinsics.checkNotNull(obj4);
String var5 = var11.append(obj4.getName()).toString();
!!总结:
如果obj4为空,则checkNotNull会抛出空指针异常。
加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常。!!必须慎用啊!!!!
目录
先抛出个结论:
? ?:的使用方法
? ?:结论:
!!的使用方法
!!总结:
先抛出个结论:
? 问号修饰,两种使用方式
- ?放在类名后面修饰表示对象可空;
- ?放在对象后修饰,则代表如果对象为空,则不执行后面的代码
?: 问号冒号修饰符
- ?:放在对象后面,代表如果对象为空,执行 ?: 后面的代码
!! 叹号修饰符
- !! 放在对象后面,表示即使对象为空我也要往下执行,可能会抛出空指针异常
//用于测试的对象返回器
class ObjectReturner<T> {
var r : Boolean = false
var obj : T? = null
constructor(r : Boolean , obj: T){
this.r = r
this.obj = obj
}
fun getObjMethod() : T?{
return obj.takeIf { r } //如果r为true返回obj,如果r为false返回null
}
}
data class Student(val name : String , val age : Int)
? ?:的使用方法
var obj4: Student? = ObjectReturner(false , stu1).getObjMethod()
println("obj4.name = ${obj4?.name}")
obj4.run {
println(this)
} ?: println("怎么返回空了呢")
上面的方法,永远不会执行到 ?: 后面的语句因为getObjMethod()即使返回空也执行到了run方法,最终打印null。
println("obj4.name = ${obj4?.name}")如果这里不加问号直接访问obj4的属性是编译不过的,因为obj4可能为null。
而使用obj4.run可以不加问号是可以编译过的(无语了)
分析这里的原因要看kotlin翻译成java后的代码
obj4.run{println(this)}的反编译结果
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
String var5 = "obj4.name = " + (obj4 != null ? obj4.getName() : null); //看这里
System.out.println(var5); //这里是关键
int var7 = false;
System.out.println(obj4);
obj4.run之所以不用加?就可以编译通过,就是因为翻译成java后obj4.run压根就没有使用obj4的任何方法或者属性。因为run方法也不是obj4的成员方法,所以可以正常编译通过,执行也不会报异常。
obj4?.run{println(this)}的反编译结果
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
String var5 = "obj4.name = " + (obj4 != null ? obj4.getName() : null);//看这里
System.out.println(var5);
if (obj4 != null) {//看这里 是 ? 翻译后的java代码
int var7 = false;
System.out.println(obj4);
} else { //看这里 是 ?: 翻译后的java代码
var5 = "怎么返回空了呢";
System.out.println(var5);
}
当加上了?以后调用run方法,翻译后的结果自动加上了 obj4 != null 的判断。
? ?:结论:
- 我们在调用方法或者使用属性之前加上了?,翻译后的java代码其实就是一个if判断,而使用 ?:则翻译后的java代码其实就是加了一个else
!!的使用方法
如果一个对象是用 ? 修饰的,表示此对象可能为空,这时如果你在使用这个对象的时候必须在对象后面加上 "?" 或者 "!!"否则是编译不过的
- 加上 "?" 上文已经介绍过了,java翻译后会自动加上if判断,如果为空则不执行。
- 加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常
var obj4: Student? = ObjectReturner(false , stu1).getObjMethod()
println("obj4.name = ${obj4!!.name}")
翻译后的java代码:
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
StringBuilder var11 = (new StringBuilder()).append("obj4.name = ");
Intrinsics.checkNotNull(obj4);
String var5 = var11.append(obj4.getName()).toString();
!!总结:
如果obj4为空,则checkNotNull会抛出空指针异常。
加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常。!!必须慎用啊!!!!
目录
先抛出个结论:
? ?:的使用方法
? ?:结论:
!!的使用方法
!!总结:
先抛出个结论:
? 问号修饰,两种使用方式
- ?放在类名后面修饰表示对象可空;
- ?放在对象后修饰,则代表如果对象为空,则不执行后面的代码
?: 问号冒号修饰符
- ?:放在对象后面,代表如果对象为空,执行 ?: 后面的代码
!! 叹号修饰符
- !! 放在对象后面,表示即使对象为空我也要往下执行,可能会抛出空指针异常
//用于测试的对象返回器
class ObjectReturner<T> {
var r : Boolean = false
var obj : T? = null
constructor(r : Boolean , obj: T){
this.r = r
this.obj = obj
}
fun getObjMethod() : T?{
return obj.takeIf { r } //如果r为true返回obj,如果r为false返回null
}
}
data class Student(val name : String , val age : Int)
? ?:的使用方法
var obj4: Student? = ObjectReturner(false , stu1).getObjMethod()
println("obj4.name = ${obj4?.name}")
obj4.run {
println(this)
} ?: println("怎么返回空了呢")
上面的方法,永远不会执行到 ?: 后面的语句因为getObjMethod()即使返回空也执行到了run方法,最终打印null。
println("obj4.name = ${obj4?.name}")如果这里不加问号直接访问obj4的属性是编译不过的,因为obj4可能为null。
而使用obj4.run可以不加问号是可以编译过的(无语了)
分析这里的原因要看kotlin翻译成java后的代码
obj4.run{println(this)}的反编译结果
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
String var5 = "obj4.name = " + (obj4 != null ? obj4.getName() : null); //看这里
System.out.println(var5); //这里是关键
int var7 = false;
System.out.println(obj4);
obj4.run之所以不用加?就可以编译通过,就是因为翻译成java后obj4.run压根就没有使用obj4的任何方法或者属性。因为run方法也不是obj4的成员方法,所以可以正常编译通过,执行也不会报异常。
obj4?.run{println(this)}的反编译结果
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
String var5 = "obj4.name = " + (obj4 != null ? obj4.getName() : null);//看这里
System.out.println(var5);
if (obj4 != null) {//看这里 是 ? 翻译后的java代码
int var7 = false;
System.out.println(obj4);
} else { //看这里 是 ?: 翻译后的java代码
var5 = "怎么返回空了呢";
System.out.println(var5);
}
当加上了?以后调用run方法,翻译后的结果自动加上了 obj4 != null 的判断。
? ?:结论:
- 我们在调用方法或者使用属性之前加上了?,翻译后的java代码其实就是一个if判断,而使用 ?:则翻译后的java代码其实就是加了一个else
!!的使用方法
如果一个对象是用 ? 修饰的,表示此对象可能为空,这时如果你在使用这个对象的时候必须在对象后面加上 "?" 或者 "!!"否则是编译不过的
- 加上 "?" 上文已经介绍过了,java翻译后会自动加上if判断,如果为空则不执行。
- 加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常
var obj4: Student? = ObjectReturner(false , stu1).getObjMethod()
println("obj4.name = ${obj4!!.name}")
翻译后的java代码:
Student obj4 = (Student)(new ObjectReturner(false, stu1)).getObjMethod();
StringBuilder var11 = (new StringBuilder()).append("obj4.name = ");
Intrinsics.checkNotNull(obj4);
String var5 = var11.append(obj4.getName()).toString();
!!总结:
如果obj4为空,则checkNotNull会抛出空指针异常。
加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常。!!必须慎用啊!!!!