当前位置: 首页>编程语言>正文

android kotlin 常用函数 kotlin !!

目录

先抛出个结论:

? ?:的使用方法

? ?:结论:

!!的使用方法

!!总结:


先抛出个结论:

? 问号修饰,两种使用方式

  • ?放在类名后面修饰表示对象可空;
  • ?放在对象后修饰,则代表如果对象为空,则不执行后面的代码

?: 问号冒号修饰符

  • ?:放在对象后面,代表如果对象为空,执行 ?: 后面的代码

!! 叹号修饰符

  • !! 放在对象后面,表示即使对象为空我也要往下执行,可能会抛出空指针异常
//用于测试的对象返回器
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会抛出空指针异常。

加上 "!!" 则表示你已经非常确定对象是不为空的,强制编译通过。但是如果最终对象是空的,则会抛出空指针异常。!!必须慎用啊!!!!


https://www.xamrdz.com/lan/5um1924463.html

相关文章: