Kotlin第二讲——数据类型与Java的对比

内容简介:通过前文的数据类型介绍,我们今天来看一下 Kotlin 与 Java 间的数据类型类型对比。

严格的数据类型验证

java 的世界中,基本数据数据类型不同也是可以赋值操作的( java 处于睁一只眼闭一只眼的情况)例如:

public static void main(String[] args) {	
    int a = 10;	
    /**	
     * 这种情况,java 是支持的,因为不存在精度丢失的情况	
     */	
    long b = a;	
}

Kotlin 具有严格的数据类型判断,不同的类型是不允许赋值操作的。如:

fun main() {	
    val a:Int = 10	
    /**	
     * 将 Int 类型的 a 赋值给 Long 类型的 b ,必须要将变量 a 转换成 Long 类型	
     */	
    val b:Long = a.toLong()	
}

==  和 equals

符合 == 的含义变成了equals

在 java 的世界中 == 的本质都是在对比 2 个数字的值是否相同(引用类型对比地址,地址也是一个 int 类型的数字)。我前面说过 kotlin 已经不存在基本数据类型,所以 == 的含义也发生了变化,全部变成了调用 equals 方法。如:

class MyInt {	
    var value = 0	
    /**	
     * 只要重写equals方法,就可以实现对象的==比较	
     */	
    override fun equals(other: Any?): Boolean {	
        if (other is MyInt){	
           return other.value == this.value	
        }	
        return false	
    }	
}

这里是不是可以联想到Kotlin的 String 字符串,为何直接可以使用 ==做字符串相同比较呢?

null 与非 null 类型

kotlin 中定义的变量类型,不光需要指定数据类型,还需要指定是否可为 null 的类型。定义可 null 和不可 null 类型:

fun main() {	
    /**	
     * 定义可空字符串,只需要在数据类型后面加 ?	
     */	
    val str: String? = null	
    /**	
     * 普通定义的变量是不可 null 类型,需要赋值.并在后面调用的过程中,必须确保不可为 null	
     */	
    val noNStr: String = "我是不可空字符串"	
}

这里补充一点,kotlin 调用java方法返回的对象,会是新的类型 ?! 。这种类的在kotlin中属于不可为 null 的类型。但是 java 返回的是一个 null 的话,kotlin直接调用,就会报 空指针异常。

聪明的空类型判断

在java的编程世界中,最常见的就是 NullPointerException 。kottlin 的设计师为我们想到了这个头疼的问题,在编码的过程中尽量规避这个异常(当然不代表100%规避)。例如:

fun main() {	
    /**	
     * 定义可空字符串	
     */	
    val str: String? = null	
    val noNStr: String = "我是不可空字符串"	
    /**	
     *  在后续的使用过程中,可 null 的对象,都会有一个判断	
     *  字段名加?代表,如果 str 为 null 就返回 null	
     */	
    val length = str?.length	
    /**	
     *  字段名加 !! 代表强制 str 不可能为 null ,这样如果也会执行去长度方法。如果 str 为 null 就会抛异常	
     */	
    val length2 = str!!.length	
}
运用方式解释
val str: String? = null定义变量的时候,代表可null类型
str?.length属性方法调用时候,如果对象为null,不调用方法,直接返回null
?:若前面的表达式,结果为null直接调用,后面的表达式

当时 ?: 和 str?.length 理解的不是很清晰,本质上这2个语法是不同的功能。我就是犯了这个错误。。例如:

fun main() {	
    val str:String?=null	
    /**	
     * 我们经常写的语句,对象为null返回逻辑,可以缩写成:	
     */	
    str?:return	
}

经常写适配器,长度的方法:

/**	
 * 我们经常写的adapter长度方法	
 */	
fun getSize(): Int {	
    return datas?.size ?: 0	
}

智能类型转换

在java 中判断一个对象类型,使用关键词 instanceof 。 在Kotlin 中使用 is 关键词,你以为就是缩短了关键词这么简单吗? kotlin 隐藏着一个类型转换的过程。例如写了个 if 语句,逻辑判断我是不是程序员?如果是,if 内的逻辑会自动将我转换成程序员,并持有程序员的特性。例如:

下方内容存在部分,kotlin 类的知识,后续会讲。

/**	
 * 定义 程序员 子类	
 */	
class CodePople(name: String, age: Int) : People(name, age) {	
    /**	
     * 定义敲代码方法	
     */	
    fun codeing() {	
        println("敲代码")	
    }	
}	
fun main() {	
    /**	
     * 定义我的数据类型,我是一个程序员(注意我这里定义的类型是 People )	
     */	
    val my: People = CodePople("阿文", 18)	
    /**	
     * 类型判断	
     */	
    if (my is CodePople) {	
        /**	
         * 重点: 可以看到我已经可以直接调用程序员的方法了. my 类型已经自动转换成了 CodePople	
         */	
        my.codeing()	
    }	
}

你以为这样就结束了?就这么点小智能?当然不是,还记得 kotlin 中存在 null 类型和不可为 null 吗?可null 类型的变量,是不可以赋值给不可为 null 的变量的哦(印证了 kotlin 中类型的赋值的严格校验)。

kotlin 中可 null & 不可 null 的智能转换:

fun main() {	
    /**	
     * 定义可 null 变量	
     */	
    var nullString: String? = null	
    /**	
     * 定义不可 null 变量	
     */	
    var str = "1231"	
    /**	
     * 如果可 null 变量,为空返回	
     */	
    nullString ?: return	
    /**	
     * 你会发现可 null 变量,已经智能转换成,不可为 null 的变量了	
     */	
    str = nullString	
}

val 与 var 的区别

kotlin 中定义变量需要使用 val 与 var 关键词

  • val修饰,定义不可变变量。类似java中final修饰(并不是完全相同)

  • var修饰,定义可变变量。

val 定义变量是不可以修改的,并且要在定义的时候初始化或者委托给另外方法(委托的概念后续会讲)。kotlin 中 val 的定义变量都有1个隐藏的方法 get 方法,当获取本变量的值的时候,就会调用。var 定义的可变变量,都有2个隐藏的方法 get & set方法,当获取本变量的值调用 get,设置变量的值时调用 set 。

例如:

class CoreDemo {	
    /**	
     * 例如这个方法,可以修改值,如果内容为空,就展示另外一个内容	
     */	
    val str: String = ""	
        get() {	
            // 对于field就(幕后字段),他就是修改当前变量字段值	
            return if (field.isEmpty()) {	
                "我不能为null"	
            } else {	
                field	
            }	
        }	
    var str2: String = ""	
        /**	
         * 当获取值的时候调用	
         */	
        get() {	
            if (field == "new")	
                return "old"	
            else {	
                field	
            }	
        }	
        /**	
         * 当设置新值的时候调用	
         */	
        set(value) {	
            /**	
             * 如果设置的值时候new,不允许修改	
             */	
            if (value != "new") {	
                field = value	
            }	
        }	
}

kotlin 中的 val 和 java 中的 final 修饰的变量是存在不同的哦。

is 关键字

java中我们经常使用 instanceof 判断类型。kotlin中不存在词关键词了,与之替换的是 is 关键词

fun main() {	
    val d = 0	
    if (d is Number){	
        println("这家伙是个数")	
    }	
}

as 和安全的类型转换

java中有强制类型转换(直接前面加 ())。kotlin中的强转变成了使用关键词 as 。

fun main() {	
    val d = 0	
    /**	
     * 使用关键词as,当然这样转换肯定会抛出异常(int到double使用toDouble()方法)	
     * class java.lang.Integer cannot be cast to class java.lang.Double	
     */	
    val double = d as Double	
}
kotlin中独有安全类型转换
fun main() {	
    val d = 0	
    /**	
     * 使用关键词as?,理论上会抛出以下异常	
     * class java.lang.Integer cannot be cast to class java.lang.Double	
     * 但是使用的as?,如果转换异常,会返回null(再配合?:语法,简直是天衣无缝),不会抛出异常	
     */	
    val defaultValue = 0.0	
    val double = d as? Double ?: defaultValue	
    println(double)	
}

延迟加载

前面说过,kotlin 的变量类型,新增了可 null 和不可 null。但是有时候特殊情况,我们知道这个变量是不可为 null 的,但是初始化这个变量,还需要其他运行时候产生的条件,可以通过 lateinit 关键词。

class CoreDemo {	
    /**	
     * 延迟初始化 lateinit var	
     * 个人意见,能规避吊这种写法,就规避掉.打破了kotlin的非空安全机制	
     */	
    lateinit var value: String	
    fun test() {	
        value = ""	
    }	
}

总结

在学习 kotlin 数据类型篇章过程中,发现相比较java来说,kotlin 去其糟粕取其精华。在数据类型这块,kotlin 对比 java 做的更加的好。相比来说 java 的强类型语言,kotlin 给我的感觉越来越像javaScript语言靠近。智能类型推倒,智能类型转换,都是相当不错的设计方案。koltin 在经常出现的 null 指针设计理念还是很惊艳的,将这种异常大部分暴露在编译期。kotlin 没有 java 的基本数据类型的概念了。kotlin 都将 java 的基本类型,进行了包装(类似 java 的 Integer 等)。

--END--

识别二维码,关注我们

640?wx_fmt=png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值