文章目录

  • 一、Kotlin的发展历程
  • 二、Kotlin相比于Java的优势
  • 三、Kotlin的工作原理
  • 四、如何运行Kotlin代码
  • 五、Kotlin语法
    • 1、变量
    • 2、函数
    • 3、逻辑控制
      • 3-1、if条件语句
      • 3-2、when条件语句
      • 3-3、for-in循环语句
    • 4、面向对象编程
      • 4-1、类与对象
      • 4-2、继承
      • 4-3、接口
      • 4-4、数据类
      • 4-5、单例类
    • 5、Lambda编程
      • 5-1、集合的创建
      • 5-2、Lambda表达式
      • 5-3、集合的函数式API
      • 5-4、Java函数式API
    • 6、空指针检查
      • 6-1、可空类型系统
      • 6-2、判空辅助工具
    • 7、Kotlin中的小魔术
      • 7-1、字符串内嵌表达式
      • 7-2、函数参数默认值

一、Kotlin的发展历程

2011年,JetBrains发布了Kotlin的第一个版本,并在2012年将其开源。

2016年Kotlin发布了1.0正式版,代表着Kotlin语言已经足够成熟和稳定了,并且JetBrains也在自家的旗舰IDE开发工具IntelliJ IDEA中加入了Kotlin的支持。

2017年Google宣布Kotlin正式成为Android开发一级语言,并且Android Studio也加入了对Kotlin的支持。

2019年Google正式宣布了Kotlin First,未来提供的官方API也将会以Kotlin版本为主。


二、Kotlin相比于Java的优势

  • 语法更加简洁,对于同样的功能,使用Kotlin开发的代码量可能会比使用Java开发的减少50%甚至更多;
  • 法更加高级,相比于Java比较老旧的语法,Kotlin增加了很多现代高级语言的语法特性,使得开发效率大大提升;
  • 语言更加安全,Kotlin几乎杜绝了空指针这个全球崩溃率最高的异常;
  • 和Java是100%兼容的,Kotlin可以直接调用使用Java编写的代码,也可以无缝使用Java第三方的开源库。这使得Kotlin在加入了诸多新特性的同时,还继承了Java的全部财富;

三、Kotlin的工作原理

Kotlin可以做到和Java 100%兼容,这主要是得益于Java虚拟机的工作机制。

其实Java虚拟机并不会直接和你编写的Java代码打交道,而是和编译之后生成的class文件打交道。

而Kotlin也有一个自己的编译器,它可以将Kotlin代码也编译成同样规格的class文件。

Java虚拟机不会关心class文件是从Java编译来的,还是从Kotlin编译来的,只要是符合规格的class文件,它都能识别。

也正是这个原因,JetBrains才能以一个第三方公司的身份设计出一门用来开发Android应用程序的编程语言。


四、如何运行Kotlin代码

第一种方法是使用IntelliJ IDEA:

第二种方法是在线运行Kotlin代码。JetBrains专门提供了一个可以在线运行Kotlin代码的网站,地址是:https://try.kotlinlang.org

第三种方法是使用Android Studio。在任意Android工程中创建一个Kotlin文件,并编写一个main()函数,即可运行main()函数中的Kotlin代码:


五、Kotlin语法

1、变量

Kotlin中定义一个变量,只允许在变量前声明两种关键字:valvar

  • val(value的简写):用来声明一个不可变的变量,这种变量在初始赋值之后就再也不能重新赋值,对应Java中的final变量;
  • var(variable的简写):用来声明一个可变的变量,这种变量在初始赋值之后仍然可以再被重新赋值,对应Java中的非final变量;
fun main() {val a = 10var b = 5printIn("a="+a);printIn("b="+b);
}

Kotlin完全抛弃了Java中的基本数据类型,全部使用了对象数据类型。在Java中int是整型变量的关键字,而在Kotlin中Int变成了一个类,它拥有自己的方法和继承结构。

2、函数

fun methodName(param1: Int, param2: Int): Int {return 0
}
  • fun(function的简写):定义函数的关键字,无论定义什么函数,都一定要使用fun来声明;
  • methodName:函数名,良好的编程习惯是函数名最好要有一定的意义,能表达这个函数的作用是什么;
  • 函数名后面的一对括号中,可以声明该函数接收什么参数;
  • 括号后面的部分是可选的,用于声明该函数会返回什么类型的数据。如果不需要返回任何数据,这部分可以不写;
  • 两个大括号之间的内容就是函数体了,可以在这里编写函数的具体逻辑;

当一个函数的函数体中只有一行代码时,可以使用单行代码函数的语法糖:

fun methodName(param1: Int, param2: Int) = 0
  • 使用这种写法,可以直接将唯一的一行代码写在函数定义的尾部,中间用等号连接即可;
  • return关键字也可以省略,等号足以表达返回值的意思;
  • Kotlin还拥有出色的类型推导机制,可以自动推导出返回值的类型;

3、逻辑控制

3-1、if条件语句

Kotlin中的if语句相比于Java有一个额外的功能:它是可以有返回值的,返回值就是if语句每一个条件中最后一行代码的返回值:

fun largerNumber(num1: Int, num2: Int): Int {val value = if(num1 > num2) {num1}else {num2}return value
}

也可以写成如下:

fun largerNumber(num1: Int, num2: Int): Int {return if(num1 > num2) {num1}else {num2}
}

当一个函数只有一行代码时,可以省略函数体部分,直接将这一行代码使用等号串联在函数定义的尾部。虽然largerNumber()函数不止只有一行代码,但是它和只有一行代码的作用是相同的,只是return了一下if语句的返回值而已,符合该语法糖的使用条件,那么代码可以进一步精简:

fun largerNumber(num1: Int, num2: Int) = if(num1 > num2) {num1
}else {num2
}

最后,还可以将上述代码再精简一下,直接压缩成一行代码:

fun largerNumber(num1: Int, num2: Int) = if(num1 > num2) num1 else num2

3-2、when条件语句

当需要判断的条件非常多的时候,可以考虑使用when语句来替代if语句,when和Java中的switch差不多

fun getScore(name: String) = when(name) {"Tom" -> 86       //name=="Tom",返回77"Jim" -> 77       //"Jack" -> 95     //"Lily" -> 100        //else -> 0          //default返回0
}

除了精确匹配之外,when语句还允许进行类型匹配:

fun checkNumber(num: Number) {when(num) {is Int -> printIn(“number is Int”);                  //num是Int类型is Double -> printIn("number is Double")        //num是Double类型else -> printIn("number not support")            //}
}

when的分支条件可以为任意表达式:

fun log(any: Any) {when(any) {"1" -> print("输入的内容为数字1")is String -> print("输入的内容是String类型的任意变量")setOf("0", "A") -> print("输入的内容是数字0和字母A的集合")Person.Dad.personName -> print("输入的内容是枚举类Person中变量Dad的姓名")}
}

when可以接收任意表达式为分支条件,而switch只能接收常量为分支条件,显然when语句在功能实现上会大大提高我们的效率和代码可读性;

when可以不带任何参数

fun log(any: Any) {when {any is Int -> print("输入的内容是Int类型的任意变量")any is String -> print(输入的内容是String类型的任意变量)}
}

注意:当when语句无参时,分支条件必须是任意的boolean表达式。

3-3、for-in循环语句

Kotlin可以用如下代码来表示一个区间(闭区间):

val range = 0..10       //[0,10]

也可以使用关键字until关键字来创建一个左闭右开的区间:

val range = 0 until 10      //[0,10)

如果想创建一个降序的区间,可以使用downTo关键字:

val range = 10 downTo 1

有了区间之后,就可以通过for-in循环来遍历这个区间了:

fun main() {for(i in 0..10) {println(i)}
}

遍历过程中如果想跳过其中的一些元素,可以使用step关键字,step定义步数,默认为1,就是正常遍历:

fun main() {for(i in 0 until 10 step 2) {println(i)}
}

4、面向对象编程

4-1、类与对象

可以使用如下代码定义一个类,以及声明它所拥有的字段和函数:

class Person {var name = ""var age = 0fun eat() {println(name + " is eating. He is " + age + " years old.")}
}

然后使用如下代码创建对象,并对对象进行操作:

fun main() {val p = Person();p.name = "Jack"p.age = 19p.eat()
}

4-2、继承

Kotlin中的一个类默认是不可以被继承的,如果想要让一个类可以被继承,需要主动声明oepn关键字:

open class Person {......
}

要让另一个类去继承Person类,则需要使用冒号关键字:

class Student : Person() {var sno = ""var grade = 0
}

现在Student类中就自动拥有了Person类中的字段和函数,还可以定义自己独有的字段和函数;

4-3、接口

Kotlin中定义接口的关键字和Java中是相同的,都是使用interface:

interface Study {fun readBooks()fun doHomework()
}

而Kotlin中实现接口的关键字变成了冒号,和继承使用的是同样的关键字:

class Student(val name: String, val age: Int) : Study {override fun readBooks() {println(name + " is reading.")}override fun doHomeword() {println(name + " is doing homework.")}
}

4-4、数据类

Kotlin中使用data关键字可以定义一个数据类:

data class Cellphone(val brand: String, val price: Double)

Kotlin会根据数据类的主构造函数中的参数将equals()、hashCode()、toString()等固定且无实际逻辑意义的方法自动生成,从而大大减少了开发的工作量;

4-5、单例类

Kotlin中使用object关键字可以定义一个单例类;

object Singleton {fun singletonTest() {println("singletonTest is called.")}
}

而调用单例类中的函数比较类似于Java中静态方法的调用方式:

Singleton.singletonTest()

这种写法虽然看上去像是静态方法的调用,但其实Kotlin在背后自动帮我们创建了一个Singleton类的实例,并且保证全局只会存在一个Singleton实例;

5、Lambda编程

5-1、集合的创建

初始化一个List集合

val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")

初始化一个Set集合

val set = setOf("Apple", "Banana", "Orange", "Pear", "Grape")

初始化一个Map集合

val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)

5-2、Lambda表达式

Lambda就是一小段可以作为参数传递的代码,正常情况下,我们向某个函数传参时只能传入变量,而借助Lambda却允许传入一小段代码:

{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}

首先最外层是一对大括号,如果有参数传入到Lambda表达式中的话,我们还需要声明参数列表,参数列表的结尾使用一个->符号,表示参数列表的结束以及函数体的开始,函数体中可以编写任意行代码,并且最后一行代码会自动作为Lambda表达式的返回值

5-3、集合的函数式API

集合中的map函数是最常用的一种函数式API,它用于将集合中的每个元素都映射成一个另外的值,映射的规则在Lambda表达式中指定,最终生成一个新的集合。比如,这里我们希望让所有的水果名都变成大写模式,就可以这样写:

fun main() {val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")val newList = list.map({fruit: String -> fruit.toUpperCase()})for(fruit in newList) {println(fruit)}
}

  • 当Lambda参数是函数的最后一个参数时,可以将Lambda表达式移到函数括号的外面;
  • 如果Lambda参数是函数的唯一一个参数的话,还可以将函数的括号省略;
  • 由于Kotlin拥有出色的类型推导机制,Lambda表达式中的参数列表其实在大多数情况下也不必声明参数类型;
  • 当Lambda表达式的参数列表中只有一个参数时,也不必声明参数名,而是可以使用it关键字来代替

因此,Lambda表达式的写法可以进一步简化成如下方式:

val newList = list.map{it.toUpperCase()}

5-4、Java函数式API

如果我们在Kotlin代码中调用了一个Java方法,并且该方法接收一个Java单抽象方法接口参数,就可以使用函数式API。Java单抽象方法接口指的是接口中只有一个待实现方法,如果接口中有多个待实现方法,则无法使用函数式API。

举个例子,Android中有一个极为常用的点击事件接口OnClickListener,其定义如下:

public interface OnClickListener {void onClick(View v);
}

可以看到,这是一个单抽象方法接口。假设现在我们拥有一个按钮button的实例,就可以使用函数式API的写法来注册这个按钮的点击事件:

button.setOnClickListener { v ->
}

6、空指针检查

空指针是一种不受编程语言检查的运行时异常,只能由程序员主动通过逻辑判断来避免,但即使是最出色的程序员,也不可能将所有潜在的空指针异常全部考虑到

public void doStudy(Study study) {study.readBooks();study.doHomework();
}

这段Java代码安全吗?不一定,因为这要取决于调用方传入的参数是什么,如果我们向doStudy()方法传入了一个null参数,那么毫无疑问这里就会发生空指针异常。因此,更加稳妥的做法是在调用参数的方法之前先进行一个判空处理,如下所示:

public void doStudy(Study study) {if (study != null) {study.readBooks();study.doHomework();}
}

6-1、可空类型系统

Kotlin中引入了一个可空类型系统的概念,它利用编译时判空检查的机制几乎杜绝了空指针异常

fun doStudy(study: Study) {study.readBooks()study.doHomework()
}

这段代码看上去和刚才的Java版本并没有什么区别,但实际上它是没有空指针风险的,因为Kotlin默认所有的参数和变量都不可为空,所以这里传入的Study参数也一定不会为空,可以放心地调用它的任何函数。

Kotlin提供了另外一套可为空的类型系统,就是在类名的后面加上一个问号。比如,Int表示不可为空的整型,而Int?就表示可为空的整型;String表示不可为空的字符串,而String?就表示可为空的字符串。

使用可为空的类型系统时,需要在编译时期就把所有的空指针异常都处理掉才行。

6-2、判空辅助工具

Kotlin提供了一系列的辅助工具,使开发者能够更轻松地进行判空处理。
?. 操作符表示当对象不为空时正常调用相应的方法,当对象为空时则什么都不做。比如:

if (a != null) {a.doSomething()
}

这段代码使用?.操作符就可以简化成:

a?.doSomething()

?: 操作符表示如果左边表达式的结果不为空就返回左边表达式的结果,否则就返回右边表达式的结果。比如:

val c = if (a ! = null) {
a
} else {
b
}

这段代码的逻辑使用?:操作符就可以简化成:

val c = a ?: b


结合使用?.操作符和let函数也可以对多次重复调用的某个变量统一进行判空处理:

fun doStudy(study: Study?) {study?.let {it.readBooks()it.doHomework()}
}

7、Kotlin中的小魔术

7-1、字符串内嵌表达式

在Kotlin中,我们可以直接将表达式写在字符串里面,即使是构建非常复杂的字符串,也会变得轻而易举。

Kotlin中字符串内嵌表达式的语法规则如下:

"hello, ${obj.name}. nice to meet you!"

当表达式中仅有一个变量的时候,还可以将两边的大括号省略:

"hello, $name. nice to meet you!"

7-2、函数参数默认值

Kotlin允许在定义函数的时候给任意参数设定一个默认值,这样当调用此函数时就不会强制要求调用方为此参数传值,在没有传值的情况下会自动使用参数的默认值。语法格式如下:

fun printParams(num: Int, str: String = "hello") {println("num is $num , str is $str")
}

这里给printParams()函数的第二个参数设定了一个默认值,这样当调用printParams()函数时,可以选择给第二个参数传值,也可以选择不传,在不传的情况下就会自动使用默认值。

Android第二课-----Kotlin入门相关推荐

  1. Android Studio和Kotlin入门

    Welcome to the series of tutorials on Android Development with Kotlin. This series is designed with ...

  2. 致Android开发者的Kotlin入门

    Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Google玩儿Android的人,我们必须尽快了解和使用Kotlin语言. 不过Kotlin毕竟是语言级 ...

  3. 【Jsp】第二课 Servlet入门学习(一)

    什么是Servlet } servlet是由sun公司提供的一门用于开发动态web资源的技术 } Servlet的核心是javax.servlet.Servlet接口,所有的Servlet 必须实现这 ...

  4. Android 第二课 Intent

    上一节,掌握了活动的创建,但是在启动器中点击应用的图标只会进入到该应用的主活动,那么,如何从主活动跳转到其他活动呢? 显式Intent Intent有多个构造函数,其中一个是Intent(Contex ...

  5. 【Python】第二课 python入门学习

    2.1 print的简单使用 # print 做算术运算print(3+5)print(4*4)print(6/2)print(12-2)print(33 % 5)# print 做多行字符串打印pr ...

  6. 第二课.PyTorch入门

    什么是PyTorch Pytorch是一个基于Python的科学计算库,类似于Numpy,但可以使用GPU,可灵活开展深度学习实验,其数据结构tensor类似于ndarray,但tensor可以在GP ...

  7. android 集合 内存泄漏,Android内存泄漏第二课--------(集合中对象没清理造成的内存泄漏 )...

    一.我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大.如果这个集合是static的话,那情况就更严重 ...

  8. Kotlin入门(19)Android的基础布局

    线性布局 线性布局LinearLayout是最常用的布局,顾名思义,它下面的子视图像是用一根线串了起来,所以其内部视图的排列是有顺序的,要么从上到下垂直排列,要么从左到右水平排列.排列顺序只能指定一维 ...

  9. Android Studio上Kotlin的入门,移动应用系统开发

    Kotlin入门 为什么选择Kotlin Kotlin是什么 Kotlin的优势 第一个Kotlin应用 Kotlin的基本语法规则 变量 函数 匿名函数 字符串模板 注释 Null 安全 类型检测和 ...

最新文章

  1. python 抛出异常raise
  2. Linux终端关闭屏幕显示,使用命令行关闭监视器
  3. Python_序列对象内置方法详解_String
  4. Leecode240. 搜索二维矩阵 II——Leecode每日一题系列
  5. Tomcat中实现websocket和browser端访问
  6. 通过键盘上下键 JS事件,控制候选词的选择项
  7. Java当中Collections的用法
  8. 避免Java中的空指针异常
  9. 计算机专业论文范文精选,计算机毕业论文提纲范文精选
  10. 浅谈如何用We7站群平台打造垂直性政务网站
  11. Mysql 获取昨日、今日、明日凌晨时间
  12. C++ STL sort 函数的用法(自定义排序函数)
  13. JavaScript高级程序设计 第4版
  14. AlertManager警报通知 E-mail 微信 模板
  15. [VBA学习]关于Formula以及数字格式的问题
  16. php手机模板修改,pc和手机模板自动切换
  17. 8.3 案例实现(加载数据库sakila中的数据至数据仓库sakila_dw)
  18. 2202年了,“小样本”还值得卷吗?
  19. 大漠Android模拟器中控,最新如意大漠多线程中控模板,适用于手游模拟器脚本...
  20. HTML中的超链接(a元素)用法详解

热门文章

  1. 弘辽科技:淘宝直通车停了没有流量?该如何解决?
  2. 率土之滨服务器维护需要多久,率土之滨赛季多久一次,赛季更新维护需要多久...
  3. semaphore讲解
  4. 4.3 FLP不可能原理
  5. 最新ChatGPT GPT-4 相似匹配Embedding技术详解(附ipynb与python源码及视频讲解)——开源DataWhale发布入门ChatGPT技术新手从0到1必备使用指南手册(一)
  6. Guitar Pro教程之不认识的符号讲解
  7. python 讲义 马永亮_tensorflow功能?
  8. 可编程渲染管线2 自定义着色器
  9. 路由器wan口和lan口短接_我把无线路由器的LAN口和WAN口用一根网线连接起来...
  10. 什么是对象序列化?如何实现?什么情况下使用?