Kotlin入门,一篇文章就够了

Android为啥要从Java转向Kotlin

Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源。苹果公司已经在用Swift语言替代Object-C语言,Google也找到了替代Java的语言,也就是JetBrains公司(Android Studio也是用该公司的Intelli J改的)主推的Kotlin。现在将kotlin作为了编写Android的官方语言,而后会有越来越多的项目使用Kotlin。Kotlin有了强有力的亲爸JetBrains公司和Google这个干爸,自然被捧在手心了。

Kotlin在编写代码时有如下优势:

  • 代码简洁高效
  • Android Jetpack 与其他库中的 Kotlin 支持
  • 可与 Java 的一起使用
  • 空指针安全

同样,kotlin支持函数式编程、支持lambda表达式、流式API...,此处略去一万字。总之,Java是上世纪的编程语言了,当你学过了Kotlin之后 ,你会发现,之前写过那么多的代码都是在浪费生命。

语法基础

变量
    var age: Int = 0
    var num = 20
    val TYPE: Int = 100  
    var name: String = ""  

写法形如:var str: String
用var或val声明,前面是参数名,后面是参数的类型,中间用:分割

var即英文“variable”的意思,声明成一个可变变量。val即英文“value”的意思,申明的是一个不可变变量,对应的java里面的final。

kotlin中有优秀的类推导机制,age声明了变量类型,num没有声明变量类型,但是依然可以通过,是由Kotlin自动推导了类型。

常量

const
如果只读属性的值在编译期是已知的,那么可以使用 const 修饰符将其标记为编译期常量,相当于java中的public static final修饰。

空指针检查

在Kotlin里,可以用“?”表示可以为空,也可以用“!!”表示不可以为空。
给变量加上?标识,会通告所有使用该变量的地方,必须给出为空的补救措施。

     var info: String? = null

        println(info?.length)  //第一种补救:如果info为null,就不执行后面的.length代码

        println(info!!.length)  //第二种补救:这里如果为null,我自己负责info,会报出空指针,这种处理需慎用

        if (info != null) {   //第三种补救措施,如下这种同java写法
            println(info.length)
        }

      println(info?.length ?: "空数据")  //第四种补救措施,如果真的为null,则改为返回"空数据"

第二个检查方式是let函数,?.当然能解决大部分问题,但是user每使用一次?.相当于都加上了代码if(user != null),实际上在同一个函数中,我们只需要做一次非空判断就行了,这就是我们的let函数的作用,在代码块内容用it代替该对象。

user.let {
            it.login()
            it.logout()
        }
延迟初始化

在kotlin中,不会给变量默认初始化,必须初始化,也不能设置null。比如如下设置null为默认值,或者不设默认值,都是编译不通过的:

    var name: String = null
    var age: Int

这种情况我们只好用?可为空标识,那使用的时候就每次都要处理一下。那么怎么解决这种不想或者不能设置默认值的情况呢?用延迟初始化!

  • lateinit
    想在类体中引用该属性时避免空检测,用可用lateinit关键字。
    var user: User? = null
    lateinit var user: User

lateinit 不能用来修饰基本数据类型,因为基本类型的属性在类加载后的准备阶段都会被初始化为默认值。
lateinit不能修饰val变量,只能修饰可变的属性

  • by lazy
    Kotlin提供了懒加载lazy机制,在懒加载机制里,变量只有在第一次被调用时,才会初始化。lazy只适用于val对象,对于var对象,需要使用lateinit。
    private val textview: TextView by lazy {
        findViewById(R.id.tv_content) as TextView
    }
可见性修饰符

在 Kotlin 中有这四个可见性修饰符:private、 protected、 internal 和 public。 如果没有显式指定修饰符的话,默认可见性是 public。
internal:在本模块内可见

字符串拼接

将变量拼接在字符串之内,用${}来包裹变量即可

    fun StringFormat(title: String) = {
        "这里是拼接字符串${title}"
    }

字符串自动换行:

val content = """
            哈哈哈哈
            呵呵呵呵
            嘿嘿嘿嘿
        """.trimIndent()
值比较、赋值:
        println(name1.equals(name2))  //同java的equals

        println(name1 == name2)  //同equals作用,比较值的相等,这里为true

        println(name1 === name2)  //比较地址是否相等,即比较是否为同一个对象,这里为false

将条件判断的结果赋值:

        val num1 = 100
        val num2 = 101
        val max = if (num1 > num2) num1 else num2

关键字

when

用when关键字代替java中的switch使用,when作为判断,条件可为任意类型

fun whenUse(obj: Any, type: Int) {
        when(obj) {
            1 ->
                ""
            in 2..5 ->
                ""
            is String ->
                ""
            else ->
                ""
        }
    }

将when的返回值直接使用起来赋值:

var result = when(type) {
            1 ->
                "1"
            2 ->
                "2"
            3 ->
                "3"
            else ->
                "4"
        }
Any

java中所有类的父类是Object,而Kotlin中所有类的父类为Any。

object

Kotlin中没有大写的Object了,而是有小写的object,表示单例。

class SingleTon {
    object Holder {
        var instance = SingleTon()
    }
}
is

Kotlin中用is代码java中的instanceOf 来判断类型

 fun charge() {
        var type = ""
        if (type is String) {  //instanceOf

        }
    }
in使用
  • in来检查一个值是否在一个区间内
fun isLetter(c: Char) = c in 'a'..'z' || c in 'A'..'Z'   //检查字符是否为字母
  • 检查list中是否有元素name
if(name in list) {
}
init

主构造函数里不能写代码,那我们怎么初始化这个类的代码呢?Kotlin则是提供了初始化模块,基本上就是用init修饰符修饰一个{},在类初始化时执行这段代码。

    class User() {
        init {

        }
    }

数组

创建数组
        var names = arrayOf("小王", "小花", "小红", "小明")

        var ages = arrayOf(22, 19, 18)

        var array = arrayOfNulls(5)   //创建空数组
        array.set(1, "哈哈")   //赋值
数组遍历
        for (i in 1..5 step 1) {   //跳过第1步遍历

        }

        for (i in 0..names.size-1) {  //遍历names数组,相当于java里  for (int i=0:i   //带position的遍历
            
        }

in的用法:val num = 1..10,表示变量num是一个[1,10]的区间。
step表步长,表示遍历间隔的个数。

类与对象

类构造函数

在 Kotlin 中的一个类可以有一个主构造函数以及一个或多个次构造函数。如果主构造函数没有任何注解或者可见性修饰符,可以省略这个 constructor 关键字。

class User constructor(name: String, age: Int, id: Int)

class User(name: String, age: Int, id: Int)

加入次构造函数:

class User(name: String) { //主构造函数

    constructor(name: String, age: Int, id: Int): this(name) {  //次构造函数,必须去调用主构造

    }

    constructor(): this("暂无名字") { 

    }
}

分别调用三个构造函数:

        User()   //次构造
        User("小明")  //主构造
        User("小明", 18, 1)  //次构造
函数

示例:

fun function(params: String): Int {
       
}
  • params: String 函数参数
  • fun function(params: String) 无返回值函数
  • fun function(params: String): Int 有返回值函数,返回值类型为Int
  • Kotlin的函数可以声明为toplevel也就是跟class一个级别,也就是说不必非放在类里面
  • 如果一个函数只有一行代码时,kotlin允许我们直接这样写,直接省略函数体
    ,如:
fun getAddressB(id: Int, name: String) = {
        "北京"
    }

    fun getAddressC(id: Int, name: String) = "上海"  //类型自动推导

返回值类型为Unit,表示为void返回类型,在函数无返回时,一般不写Unit。

fun getAddressE(id: Int, name: String): Unit {  

}

fun getAddressE(id: Int, name: String) {  

}

多参数函数写法:

    fun setDatas(vararg value: Int) {
        for (i in value) {
            println(i)
        }
    }


Test().setDatas(0, 1, 2)
函数的默认参数值

声明函数变量时,直接给参数设置默认值,如果调用函数时对应参数缺省,那么该参数就是默认值。而在java中实现默认参数值方法则是需要自己写多个重构方法。

    fun createUser(name: String = "小明", age: Int = 20, id: Int = 1) {

    }

        createUser()
        createUser("小王")
        createUser("小红",18)
        createUser("小李", 25, 2)
创建对象

Kotlin中创建对象不再需要关键字new了,直接创建对象:

var user = User()
继承

在Kotlin中的类和方法默认是不可以被继承的,需要加上关键字open,才允许被继承。继承用":"表示,类和接口的继承都用":",类需要加()。

class VipUser : User(), Use {

}

open class User {

}

interface Use {

}
内部类
class OuterClass {

    val count = 100

    //这个叫嵌套类,不是内部类,拿不到外部类的count属性
    class InterClass {

        fun show() {
//            println(count)
        }
    }

    //加上inner声明,就为内部类,可以拿到count属性
    inner class InterClass2 {

        fun show() {
            println(count)
        }
    }
    
}
数据类

即为我们通常使用的bean类,一般在定义数据类的时候,我们需要手动实现这个类的equals()、hashcode()、toString()等方法,这些方法是必要的。但是加上data关键字后,该类会自动生成这些方法。

data class User(var name: String) {

}
单例类

在java中,单例的写法需要自己手动实现,比如用懒汉式还是饿汉式。但是在Kotlin中单例就非常简化了,只需要将class替换成object就可以了。

    object SingleTonClass {

        var params: String? = null

        fun function() {

        }
    }

    SingleTonClass.function()

    SingleTonClass.params

使用单例时不需要再获取instance实例对象了,Kotlin已经在内部帮我们创建了一个单例的实例,直接使用类名调用它的属性和方法。

compaion object(伴生对象)

在java中static表静态变量,kotlin中取消了static,用compaion object来代替它的用法。

class SingleTon {

    object Holder {
        val instance = SingleTon()
    }

    companion object {
        fun getInstance() = Holder.instance
    }
}

最后:将现有Java文件转换为Kotlin文件

我们可以将现有Java文件代码转换为Kotlin文件代码,而实现从java往kotlin上转移。可以针对单个文件,某个包,某个module,或者整个项目转为kotlin文件。
转换完成之后可能会有少量语法错误,需要手动修改一下。

Kotlin入门,一篇文章就够了_第1张图片
将kotlin代码转为java

在Tools->Kotlin->show Kotlin ByteCode,点击Decompile转回类似Java代码。


Kotlin入门,一篇文章就够了_第2张图片

你可能感兴趣的