一手遮天 Android - kotlin: 可空类型,数据类型判断(is, !is),类型转换,可空类型的相关操作符(let, ?:, ?, !!, as?),== 和 ===

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

一手遮天 Android - kotlin: 可空类型,数据类型判断(is, !is),类型转换,可空类型的相关操作符(let, ?:, ?, !!, as?),== 和 ===

示例如下:

/kotlin/Demo2.kt

/**
 * 本例用于演示 kotlin 的可空类型,数据类型判断(is, !is),类型转换,可空类型的相关操作符(let, ?:, ?, !!, as?),== 和 ===
 *
 * 注:任何类型,如果声明时不加 ? 的话都是不可为 null 的,要想为 null 则声明时必须加 ?
 */

package com.webabcd.androiddemo.kotlin

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.webabcd.androiddemo.R
import kotlinx.android.synthetic.main.activity_kotlin_helloworld.*
import java.lang.Exception

class Demo2 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin_demo2)

        sample1(); // 定义可空类型
        sample2(); // == 和 ===
        sample3(); // 可空类型的相关操作符(let, ?:, ?, !!, as?)
        sample4(); // 数据类型判断(is, !is)和类型转换
    }

    fun sample1() {
        var a: Int? = 1234;
        var b: Int? = null;
        var c: String? = null; // 注意:声明可空的引用类型时也是需要加 ? 的(包括 String 等引用类型,或自定义对象等)

        appendMessage("${a == 1234}, ${b == null}, ${c == null}"); // true, true, true
    }

    fun sample2() {
        // == 用于比较值是否相等
        // === 用于比较地址是否相等
        var a: Int? = 1234;
        var b: Int? = 1234;
        appendMessage("${a == b}, ${a === b}") // true, false

        // -128 到 127 之间的是例外,他们不会被装箱,所以他们的 == 和 === 是一样的
        var c: Int? = 123;
        var d: Int? = 123;
        appendMessage("${c == d}, ${c === d}") // true, true

        // 字符串比较特殊,他们的 == 和 === 是一样的
        var e: String? = "1234";
        var f: String = "1234";
        appendMessage("${e == f}, ${e === f}") // true, true
    }

    fun sample3() {
        var a: Int? = 1234;
        var b: Int? = null;

        // 虽然对象 null 是不可以 toString() 的,但是 toString() 方法里会有判断,如果是 null 则返回字符串 null
        // ? 左侧为 null 的话就不走右边了,并返回对象 null
        appendMessage("${b.toString() == null}, ${b.toString() == "null"}, ${b?.toString() == null}"); // false, true, true

        // ?.let 左侧为 null 就不执行右边的大括号,反之则执行
        a?.let { appendMessage("aaa") }; // 会输出 aaa
        b?.let { appendMessage("bbb") }; // 不会输出 bbb
        // ?.let 有一个参数,其代表 ?.let 左侧对象的值
        a?.let { appendMessage("$it") }     // 1234
        a?.let { p -> appendMessage("$p") } // 1234

        // ?: 左侧为 null 则返回右边的值,反之则返回左边的值
        a = a ?: 123456;
        b = b ?: 123456;
        appendMessage("$a"); // 1234
        appendMessage("$b"); // 123456

        // 虽然对象 null 是不可以 toString() 的,但是 toString() 方法里会有判断,如果是 null 则返回字符串 null
        // 通过 !! 可以对一个可空对象强行取值,如果是 null 则会抛出异常
        var c: String? = null;
        try {
            appendMessage("${c.toString()}");   // null
            appendMessage("${a!!}");            // 1234
            appendMessage("${c!!}");            // 抛异常
        } catch (ex: Exception) {
            appendMessage(ex.toString());       // kotlin.KotlinNullPointerException
        }

        // as? 转换为可空类型
        var d: String = "abc";
        var e: Int? = d as? Int;
        appendMessage("$e"); // null
        // 以下两种转换方式都是会抛错的
        // appendMessage("${d as Int}"); // java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
        // appendMessage("${d as Int?}"); // java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    }

    fun sample4() {
        var a: String? = null;
        // is 是否是指定的类型
        appendMessage("${a is String?}"); // true
        // !is 是否不是指定的类型
        appendMessage("${a !is String}"); // true

        // 类型转换的方法(包括 toString(), toByte(), toShort(), toInt(), toLong(), toFloat(), toDouble(), toChar() 等)
        var b = "123".toInt()
        // 有继承关系的类型的转换可以用 as 或 as?
        var c = 123L as Number
        var d = c as Long
        // 隐式类型转换
        var e = "abc" + 123
        appendMessage("$b, $c, $d, $e") // 123, 123, 123, abc123

        // 对于没有继承关系的类型,如果你用 as 或 as? 转换的话
        // "123" as Int     // 这个会报错 java.lang.String cannot be cast to java.lang.Integer
        // "123" as Int?    // 这个会报错 java.lang.String cannot be cast to java.lang.Integer
        // "123" as? Int    // 这个转换结果为 null
    }

    fun appendMessage(message: String) {
        textView1.append(message);
        textView1.append("\n");
    }
}

/layout/activity_kotlin_demo2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

posted @ 2021-05-31 12:06  webabcd  阅读(365)  评论(0编辑  收藏  举报