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 的智能转换:

    /**

 * 定义可 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 修饰的变量是存在不同的哦。 java 中 final 修饰的变量,在编译期就知道了该变量的值是多少。所以在引用的此变量时候就会直接使用此值(编译器替换)。 kotlin的 val 变量是不会替换的。如果想要替换使用 const 修饰

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 等)。

转载 https://mp.weixin.qq.com/s/c4...

你可能感兴趣的:(kotlin)