Android第二课-----Kotlin入门
文章目录
- 一、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中定义一个变量,只允许在变量前声明两种关键字:val
和var
- 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入门相关推荐
- Android Studio和Kotlin入门
Welcome to the series of tutorials on Android Development with Kotlin. This series is designed with ...
- 致Android开发者的Kotlin入门
Google在今年的IO大会上宣布,将Android开发的官方语言更换为Kotlin,作为跟着Google玩儿Android的人,我们必须尽快了解和使用Kotlin语言. 不过Kotlin毕竟是语言级 ...
- 【Jsp】第二课 Servlet入门学习(一)
什么是Servlet } servlet是由sun公司提供的一门用于开发动态web资源的技术 } Servlet的核心是javax.servlet.Servlet接口,所有的Servlet 必须实现这 ...
- Android 第二课 Intent
上一节,掌握了活动的创建,但是在启动器中点击应用的图标只会进入到该应用的主活动,那么,如何从主活动跳转到其他活动呢? 显式Intent Intent有多个构造函数,其中一个是Intent(Contex ...
- 【Python】第二课 python入门学习
2.1 print的简单使用 # print 做算术运算print(3+5)print(4*4)print(6/2)print(12-2)print(33 % 5)# print 做多行字符串打印pr ...
- 第二课.PyTorch入门
什么是PyTorch Pytorch是一个基于Python的科学计算库,类似于Numpy,但可以使用GPU,可灵活开展深度学习实验,其数据结构tensor类似于ndarray,但tensor可以在GP ...
- android 集合 内存泄漏,Android内存泄漏第二课--------(集合中对象没清理造成的内存泄漏 )...
一.我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大.如果这个集合是static的话,那情况就更严重 ...
- Kotlin入门(19)Android的基础布局
线性布局 线性布局LinearLayout是最常用的布局,顾名思义,它下面的子视图像是用一根线串了起来,所以其内部视图的排列是有顺序的,要么从上到下垂直排列,要么从左到右水平排列.排列顺序只能指定一维 ...
- Android Studio上Kotlin的入门,移动应用系统开发
Kotlin入门 为什么选择Kotlin Kotlin是什么 Kotlin的优势 第一个Kotlin应用 Kotlin的基本语法规则 变量 函数 匿名函数 字符串模板 注释 Null 安全 类型检测和 ...
最新文章
- python 抛出异常raise
- Linux终端关闭屏幕显示,使用命令行关闭监视器
- Python_序列对象内置方法详解_String
- Leecode240. 搜索二维矩阵 II——Leecode每日一题系列
- Tomcat中实现websocket和browser端访问
- 通过键盘上下键 JS事件,控制候选词的选择项
- Java当中Collections的用法
- 避免Java中的空指针异常
- 计算机专业论文范文精选,计算机毕业论文提纲范文精选
- 浅谈如何用We7站群平台打造垂直性政务网站
- Mysql 获取昨日、今日、明日凌晨时间
- C++ STL sort 函数的用法(自定义排序函数)
- JavaScript高级程序设计 第4版
- AlertManager警报通知 E-mail 微信 模板
- [VBA学习]关于Formula以及数字格式的问题
- php手机模板修改,pc和手机模板自动切换
- 8.3 案例实现(加载数据库sakila中的数据至数据仓库sakila_dw)
- 2202年了,“小样本”还值得卷吗?
- 大漠Android模拟器中控,最新如意大漠多线程中控模板,适用于手游模拟器脚本...
- HTML中的超链接(a元素)用法详解
热门文章
- 弘辽科技:淘宝直通车停了没有流量?该如何解决?
- 率土之滨服务器维护需要多久,率土之滨赛季多久一次,赛季更新维护需要多久...
- semaphore讲解
- 4.3 FLP不可能原理
- 最新ChatGPT GPT-4 相似匹配Embedding技术详解(附ipynb与python源码及视频讲解)——开源DataWhale发布入门ChatGPT技术新手从0到1必备使用指南手册(一)
- Guitar Pro教程之不认识的符号讲解
- python 讲义 马永亮_tensorflow功能?
- 可编程渲染管线2 自定义着色器
- 路由器wan口和lan口短接_我把无线路由器的LAN口和WAN口用一根网线连接起来...
- 什么是对象序列化?如何实现?什么情况下使用?