从事Android开发的童鞋都知道,自从去年的Google I/O大会上Kotlin被定为Android开发的官方语言以来,关于Kotlin就成为每个开发人员学习的目标,的确,Kotlin以它独有的魅力正在吸引这传统的Java程序开发人员。或许很多的童鞋已经对Kotlin进行了深入的学习,甚至已经运用到了自己的项目当中,但是还有较多同学可能只是听过Kotlin或简单了解过,本文将从宏观的角度来介绍Kotlin相关的内容。
在介绍Kotlin之前,先来安利一波,本人去年年底开始写作的关于Kotlin的书下个月就要出版了,有兴趣的可以关注下,目录如下。
Kotlin简介
Kotlin是由JetBrains开发的针对JVM、Android和浏览器的静态编程语言,目前,在Apache组织的许可下已经开源。使用Kotlin,开发者可以很方便地开发移动Android应用、服务器程序和JavaScript程序。Kotlin可以将代码编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。
Kotlin是开源的,这意味着,我们可以在GitHub上下载Kotlin的全部源代码,并对它进行代码修改再发布,Kotlin在github上的开源地址为:
https://github.com/JetBrains/kotlin 。
JetBrians
一家捷克的软件公司,是著名的IDE开发商,对很多的开发语言和平台都提供了相应的集成开发环境,比如Java的,OC的,JavaScript,PHP,C/C++等。而其中最著名的是IntelliJ IDEA ,Java的集成开发环境,被称为目前最好用的java IDE。而且Android Studio就是Google基于IntelliJ IDEA 开发的,由此可见Google和JetBrains的合作也是比较密切的。而从以上说明也可以看到JetBrains不仅实力强劲,这家公司对于语言设计更是有天然优势。Kotlin是集多家语言之大成。
Kotlin的优势
那么,相比Java等语言,Kotlin有什么优势呢?
1,语法简洁,吸引了其他语言的优点
Kotlin提供了大量的语法糖(有函数声明,类的创建,集合相关,范围运算符等等大量简洁的语法)、 Lambda表达式(Java8支持),简洁的函数表示法。并吸收了其他语言的优点:模板字符串,运算符重载,方法扩展,命名参数等。
2,安全性
Kotlin提供了安全符“?”,当变量可以为null时,必须使用可空安全符?进行声明,否则会出现编译错误。并且,Kotlin还提供了智能的类型判断功能,使用is类型判断后,编译器自动进行类型转换,父类引用可以调用子类接口,注意转换只在is的代码块中生效。
3,完全兼容Java
Kotlin的另一个优势就是可以100%的兼容Java,Kotlin和Java之间可以相互调用。使用Kotlin进行Android或者Java服务端开发,可以导入任意的Java库。
在Android Studio中可以一键转换Java代码为Kotlin代码(Code > Convert Java File to Kotlin File.),同时Kotlin代码也可以反编译成Java代码(1.Tools>Kotlin>Show Kotlin Bytecode 2.Decompile)。
4,IDE工具支持
在Google官方发布的最新版本的Android Studio 3.0上,已经默认集成了Kotlin,对于一些老版本,也可以通过插件的方式来集成Kotlin。所以,使用JetBrains提供的IDE,可以为Kotlin开发提供最佳的环境支持。就像JetBrains所说:一门语言需要工具化,而在 JetBrains,这正是我们做得最好的地方!
Kotlin是如何兼容Java的
都是Kotlin可以100%的兼容Java,那么Kotlin又是如何兼容Java的呢?下面是Kotlin的一个编译流程图。
Kotlin为什么可以兼容Java,一个主要原因是Kotlin文件在经过Kotlin编译器编译后会生成Java字节码。这跟Java文件通过Java编译器编译后生成的字节码几乎没有区别,这样JVM就能直接识别和处理Kotlin代码的功能和逻辑。
当Kotlin调用Java代码,Kotlin编译器会对调用的Java文件进行分析,以便kt文件能够生成正确的class文件。为什么这么说呢?举个列子,Java字节码有几种函数调用的方式invokespecial 、 invokeStatic 、 invokeInterface等,编译器必须知道调用的Java函数是什么类型才能生成相应的正确的字节码。而当在Java代码中调用Kotlin对象时,Kotlin生成的class文件也要输入到Java编译器,这时Java文件才能生成正确的class文件。生成的class文件打成jar包后,最终可以生成Android的APK,或供Java服务端调用。
当然,我们可以直接下载Kotlin编译器下来查看他的编译过程。Kotlin编译器的代码都是用java写的,所以使用Kotlin编译器必须要有java环境。
Kotlin语言基础
基础特性
1,变量定义
在Kotlin的语法规则中,var用来声明变量,val类似Java final,用来声明常量,语句后面不需要跟分号。变量类型可以根据变量值进行自动推导,这里Kotlin的基础类型都是对象,使用的是Java的包装类(基础类型包装成对象)。
2,函数定义
函数使用fun为关键字进行声明,变量的冒号之后是变量类型,函数的冒号之后是返回值。同时Kotlin支持在函数定义的时候声明参数的默认值,例如:
函数调用的时候可以直接调用,也可以使用命名参数,例如:
3,类声明
类名的冒号表示继承,所有类的基类称为Any(但并不是Java的Object,只包含equals、hascode、toString方法),声明构造函数要指明constructor关键字。例如:
当然,也可以直接在声明类的时候指定构造函数,对象实例化可以不写new关键字。
4,流程控制语句
Kotlin其他的流程控制基本跟Java差不多,这里主要讲下when表达式,他取代了Java的switch。例如:
when表达式其实最终是使用if/else来实现的,Kotlin保留了原来的for each循环,同时增加了区间控制。例如:
5,集合
Kotlin的集合与OC的集合相似,分为可变集合和不可变集合(lists、sets、maps 等)。kotlin中的可变集合对Java的集合进行了包装,同时它实现了一套不可变集合库。
调用上面集合的方式如下:
6,伴生对象
Kotlin中没有静态属性和方法,如果我们要创建单列,可以使用Object关键字声明类。
如果要在一个类里面声明静态成员,可以在类的内部使用伴生对象,伴生对象使用关键字companion object。
伴生对象的调用跟Java一样,通过类名.属性名称或函数名称调用。
新特性
1,空安全
在Kotlin中,对象声明分为可空引用和非空引用两种。其中非空引用的定义如下:
而可空引用需要使用安全符“?”,例如:
当调用的时候,也需要使用安全调用操作符,写作 ?. 可空调用。例如:
通过函数调用给可空引用赋值,返回的必须也是可空引用,这就在编译期间杜绝了空指针异常。但是这里要注意一点,如果从Java返回的集合,不会强制做可空检查,这个是时候如果给不可空引用赋值Java集合中的null会出现转换错误异常。
2,扩展函数
跟OC的Category一样,Kotlin也支持对API函数进行扩展。
然后,我们可以在任意Activity中直接调用。
通过反编译成Java代码可以发现,函数的扩展实质上是通过静态导入的方式实现的。
3,字符串模板
字符串中可以包含变量或者表达式,以$符号开头(这跟JSP的EL表达式有点像),比如:
4,操作符重载
Kotlin为基本的运算符提供了固定名称函数表,此部分比较多,关于这方面的内容,读者可以访问下面的内容:Kotlin操作符重载。
调用如下:
5,Lambda表达式支持
Lambda表达式的本质是一个未声明的函数,他会以表达式的形式传递。既然是函数,就由这三块组成:参数 、 方法体 和 返回值。例如,下面是一个典型的Lambda表达式。
可以看到,Lambda表达式的大括号内,箭头左边是参数,箭头右侧是方法体和返回值。
调用上面的函数,可以使用下面的调用方式。
高级特性
1,高阶函数
把函数作为参数或者是返回值的函数,Kotlin称之为高阶函数。例如:
调用高阶函数的方式如下:
当然,我们也可以声明一个局部函数,然后把他作为参数传递给另一个函数,还可以使用Lambda表达式来表示函数参数。
2,泛型
泛型的存在主要是为了消除模板代码和类型转换安全, 在Kotlin中泛型的使用基本与Java是一致的。
在Java中泛型是不变的,比如:虽然A继承B,但List和List之间没有任何关系,Java是通过泛型通配符来实现型变的:
<? extends T> 对应Kotlin的 out T 生产者
<? super T> 对应Kotlin的 in T 消费者
3,反射
反射是运行于JVM中的程序检测和修改运行时的一种行为,通过反射可以在运行时获取对象的属性和方法,这种动态获取信息以及动态调用对象方法的功能特性被称为反射机制。反射可以获取类的方法,属性,类结构等所有信息。
在Kotlin中使用Java的反射的实例如下:
jc返回的是Java的class对象,可以通过这个对象去调用调用Java的反射内容。
Kotlin中的反射如下。
要调用具体的对象时,可以不通过KClass对象,直接调用方法和访问属性。例如:
4,协程
协程(coroutine),又称微线程,是一种无优先级的子程序调度组件,由协程构建器(launch coroutine builder)启动。协程本质上是一种用户态的轻量级线程,协程的调用方式与子线程的调用方式一样,但是协程的使用更加方便灵活,但使用上协程并没有子线程那样广泛。
协程作为一种新的异步编程方式,它使用线程为资源,基于代码逻辑去实现任务之间的调度。程序使用协程可以书写线性的异步代码,没有callback,大大简化了异步编程。以下是协程使用的实例:
,关于协程更多的内容可以访问下面的链接:
https://www.kotlincn.net/docs/tutorials/coroutines-basic-jvm.html
跨平台开发
多平台支持
Kotlin的不仅仅用于Java,还可以使用它进行web js和iOS开发,所以市面上之前说Kotlin是一款基于JVM的语言是不准确的。通过Kotlin提供的Kotlin Native特性,Kotlin可以使用跨平台开发功能。目前Kotlin支持的跨平台如下图所示。
1,Kotlin用于服务端开发
使用Kotlin可用于Java服务端开发。Java与Kotlin的相互兼容性,我们可使用服务端的任意框架,同时我们可以保留老的Java代码,使用Kotlin编写新代码。Kotlin的协程特性更有助于构建服务端程序。IDE的支持和Sring框架的支持。
2,Kotlin用于Android开发
Android Studio的支持。大量的实际案列。大量可学习的APP项目。与Java兼容性允许在 Kotlin 应用程序中使用所有现有的 Android 库。
3,Kotlin用于JavaScript
使用kotlinc-js编译器将Kotlin代码转换为JavaScript(不是Kotlin或标准库的代码编译时会被忽略),Kotlin中提供了一些标准库用于JS开发,同时可以使用第三方JS库。
Kotlin Native
Kotlin Native是一种将Kotlin源码编译成不需要任何VM支持的目标平台二进制数据的技术,编译后的二进制数据可以直接运行在目标平台上,它主要包含一个基于LLVM的后端编译器的和一个Kotlin本地运行时库。设计Kotlin Native的目的是为了支持在非JVM环境下进行编程,如在嵌入式平台和iOS环境下,如此一来,Kotlin就可以运行在非JVM平台环境下。
目前,Kotlin Native主要提供了Mac、Linux和Windows三个主流平台的编译器,使用该编译器可以很轻松的编译出运行在树莓派、iOS、OS X、Windows以及Linux系统上的程序。
当然,读者可以通过Kotlin/Native的一款游戏源码来学习Kotlin Native:https://github.com/jetbrains/kotlinconf-spinner
学习资料
当然,读者还可以使用通过下面的链接来学习Kotlin相关的知识。
1.Kotlin官网
http://kotlinlang.org/
2.kotlin中文官网
https://www.kotlincn.net/
3.Google Kotlin项目学习实例
https://developer.android.com/samples/index.html?language=kotlin
4.其他文章
https://blog.csdn.net/u013448469/article/details/79403284 Kotlin反射
https://blog.csdn.net/ztguang/article/details/72511994 Kotlin Native
5,视频应用项目
https://github.com/xiangzhihong/EyeVideoClient
6,Kotlin入门与实战
第1章 Kotlin简介
1.1 Kotlin发展史
1.2 面向对象编程简介
1.2.1 面向过程编程
1.2.2 面向对象编程
1.3 Java虚拟机
1.3.1 JVM语系生态
1.2.2 Java虚拟机简介
1.2.3 Kotlin应用程序运行过程
1.4 为什么使用Kotlin
1.5 Kotlin与Java的比较
1.6小结
第2章 Kotlin初体验
2.1 Kotlin在线运行
2.2 Kotlin 1.1特性
2.2.1 JavaScript全面支持
2.2.1 JVM新特性
2.2.3 协程
2.2.4 标准库
2.3 Kotlin 1.2新特性
2.3.1 多平台支持
2.3.2 多平台环境搭建
2.3.3 特定平台申明
2.3.4 标准库支持
2.3.5 JVM特性
2.3.6 JavaScript特性支持
2.4小结
第3章 Kotlin快速入门
3.1 在Mac上搭建Kotlin开发环境
3.1.1 安装与配置JDK环境
3.1.2 安装与配置IDE
3.2 Kotlin开发IDE介绍
3.2.1 IntelliJ IDEA开发环境
3.2.2 Android Studio集成开发环境
3.3 Kotlin的编译与运行
3.3.1 命令行方式编译运行Kotlin
3.3.2 运行Kotlin REPL
2.3.3 在浏览器中运行Kotlin
2.3.4 在NodeJS中运行Kotlin
3.4 Kotlin构建方式
3.4.1 使用Gradle方式构建Kotlin
3.4.2 使用Maven方式构建Kotlin
3.4.3 使用Ant方式构建Kotlin
3.4.4 Kotlin与OSGi
3.4.5 Kotlin与kapt
3.5 编译器插件
3.5.1 全开放编译插件
3.5.2 无参编译器插件
3.6 小结
第4章 Kotlin语法基础
4.1 Kotlin编程风格
4.2变量与属性
4.2.1 变量申明
4.2.2 getter和setter
4.2.3 访问权限
4.3 基本数据类型
4.3.1 数值类型
4.3.2 字符类型
4.3.3 布尔类型
4.3.4 数组类型
4.3.5 字符串
4.4 包申明与使用
4.5 流程控制语句
4.5.1 if条件语句
4.5.2 when语句
4.5.3 for循环
4.5.4 while循环
4.5.5 返回与跳转
4.6 Kotlin运算符
4.6.1 赋值运算符
4.6.2 算数运算符
4.6.3 关系运算符
4.6.4 逻辑运算符
4.6.6 区间运算符
4.6.7 运算符优先级
4.7 运算符重载
4.7.1 一元运算符
4.7.2 二元运算符
4.7.3 位运算符
4.8 Kotlin操作符
4.8.1 冒号操作符
4.8.2 @操作符
4.8.3 $操作符
4.8.4 安全转换操作符
4.8.5 类型判断操作符
4.9 Kotlin动态类型
4.10 Kotlin空安全
4.9.1 可空类型与不可空类型
4.9.2 判空操作符
4.9.3 Elvis 操作符
4.9.4 强校验操作符
4.9.5 安全的类型转换
4.9.6 可空类型集合
4.11异常处理
4.11.1 异常类
4.11.2 自定义异常
4.11.3 try表达式
4.11.4 throw表达式
4.11.4 受检异常
4.12小结
第5章 类与接口
5.1 类
5.1.1 类的申明
5.1.2 构造函数
5.1.3 类的实例
5.2 继承
5.3 抽象类
5.4 接口
5.5 小结
第6章 扩展函数与属性
6.1 枚举
6.1.1 基本用法
6.1.2 枚举类扩展
6.2 扩展
6.2.1 扩展的动机
6.2.2 扩展原生函数
6.2.3 静态解析
6.2.4 扩展属性
6.2.5 扩展伴生对象
6.2.6 扩展的作用域
6.2.7 类中声明扩展
6.3 this表达式
6.5 小结
第7章 数据类与密封类
7.1 数据类
7.1.1 对象复制
7.1.2 序列化
7.1.3 成员解构
7.2 密封类
7.3 小结
第8章 集合与泛型
8.1集合
8.1.1 集
8.1.2 列表
8.1.3 映射
8.2 泛型
8.2.1 泛型基础
8.2.2 型变
8.2.3 声明处型变
8.2.4 类型投影
8.2.5 星号投影
8.2.6 泛型函数
8.2.7 泛型约束
8.3 小结
第9章 对象与委托
9.1 对象
9.1.1 对象表达式
9.1.2 对象申明
9.1.3 伴生对象
9.2 委托
9.2.1 类委托
9.2.2 委托属性
9.3 标准委托
9.3.1 延迟属性
9.3.2 可观察属性
9.3.3 Map委托
9.3.4 Not Null
9.3.5 局部委托属性
9.3.6 提供委托
9.4 小结
第10章 反射与注解
10.1 反射
10.1.1 类引用
10.1.2 类成员引用
10.1.3 函数引用
10.1.4 属性引用
10.1.5 构造函数引用
10.1.6 KClass反射
10.1.7 对象序列化Json
10.2 注解
10.2.1 注解声明
10.2.2 注解使用
10.2.3 注解类的构造函数
10.2.4 注解目标使用场景
10.2.5 与Java注解互调
10.2.6 注解分类
10.2.7 注解的生命周期
10.3 小结
第11章 函数与Lambda表达式
11.1 函数
10.1.1 函数基本用法
10.1.2 中缀表示法
10.1.3 函数参数
10.1.4 函数作用域
10.1.5 函数返回值
10.1.6 尾递归函数
11.2 高阶函数
11.2.1 高阶函数基本用法
11.2.2 标准高阶函数
11.3 内联函数
11.3.1 内联Lambda表达式
11.3.2内联函数声明
11.3.3非局部返回
11.3.4实例化类型参数
11.3.5内联属性
11.4 Lambda表达式与匿名函数
11.4.1 Lambda表达式语法
11.4.2 函数类型
11.4.3 匿名函数
11.4.4 闭包
11.4.5 函数显示申明
11.5 小结
第12章 协程
12.1 协程简介
12.1.1 协程与线程
12.1.2 使用协程的好处
12.2 协程开发环境
12.2.1 Gradle构建方式
12.2.2 Maven构建方式
12.3 协程基础
12.3.1 launch函数
12.3.2 共享线程池
12.3.3 阻塞与挂起
12.3.4 runBlocking函数
12.3.5 协程取消
12.3.6 协程超时
12.3.6 标准API
12.4 挂起函数
12.4.1 默认顺序执行
12.4.2 异步并发执行
12.4.3 异步样式函数
12.5 协程上下文与调度器
12.5.1 协程调度与线程
12.5.2 非限制与限制协程
12.5.3 协程与线程调试
12.5.4 协程中的子协程
12.6 通道
12.6.1 通道基础
12.6.2 通道的关闭与迭代
12.6.3 通道生产者
12.7 管道
12.7.1 管道生产与消费
12.7.2 管道与质数
12.7.3 多接受者协程
12.7.4 通道缓存
12.9 小结
第13章 IO操作与多线程
13.1 Kotlin流层次
13.1.1 字节输入流
13.1.2 字节输出流
13.1.3 字符输入流
13.1.4 字符输出流
13.1.5 字符流与字节流转换
13.2 文件IO操作
13.2.1 文件读取
13.2.2 文件写入
13.2.3 文件遍历
13.3 网络IO操作
13.4 多线程
13.4.1 线程创建
13.4.2 线程同步
13.5 小结
第14章 Kotlin DSL
14.1 DSL简介
14.1.1 DSL的设计与实现
14.1.2 DSL分类
14.2 DSL语义模型
14.2.1 依赖网络
14.2.2 产生式规则系统
14.2.3 状态机
14.3 Kotlin的DSL特性
14.4 kotlinx.html创建DSL
14.4.1 Maven方式构建
14.4.2 Gradle方式构建
14.4.3 kotlinx.html实例
14.5 Android Gradle指南
14.4.1 链式命令
14.4.2 委托
14.6 使用Kotlin与Anko进行Android开发
14.5.1 Anko简介
14.5.2 Anko核心组件与工具
14.5.3 Anko使用实例
14.7 小结
第15章 Kotlin互操作
15.1 Kotlin与Java互操作
15.1.1 在Kotlin中调用Java
14.1.2 在Java中调用Kotlin
14.1.3 JSR-305支持
15.2 Kotlin与JavaScript互操作
15.2.1 在Kotlin中调用JavaScript
14.2.2 在JavaScript中调用Kotlin
15.2.3 JavaScript模块
15.2.4 JavaScript反射
15.2.5 JavaScript DCE
15.3 小结
第16章 Kotlin Native开发
16.1 Kotlin Native
16.1.1 Kotlin Native简介
16.1.2 Kotlin Native编译器
16.1.3 编译器konan
16.2 Kotlin Native实例
16.2.1 构建Kotlin Native项目
16.2.2 添加konan插件配置
16.2.3 编写源代码
16.2.4 添加konanInterop与konanArtifacts配置
16.2.5 编译与执行
16.2.6 命令行方式编译Kotlin Native
16.3 Kotlin Native互操作
16.2.1 Kotlin Native与C语言互操作
16.2.2 Kotlin Native与OC互操作
16.4 小结
第17章 使用Kotlin与Spring Boot开发服务端
17.1 Spring Boot环境搭建
17.1.1 Spring Boot简介
17.1.2 创建Spring Boot应用程序
17.1.3 启动Spring Boot应用程序
17.1.4 应用测试
16.1.5 properties配置文件
17.2 Spring Boot之Thymeleaf模板
17.3 使用Swagger构建RESTful API
17.4 Spring Boot通过MyBatis整合Mysql数据库
17.5 Spring Boot整合Redis数据库
17.5.1 Redis简介
17.5.2 Spring Boot整合Redis
17.6 Spring Boot整合Elasticsearch
17.6.1 Elasticsearch简介
17.6.2 Spring Boot整合Elasticsearch
17.7 Spring Boot集成RabbitMQ
17.7.1 RabbitMQ简介
17.7.2 Spring Boot集成RabbitMQ
17.8 Spring Boot热部署与日志管理
17.9 Spring Framework 5.0对Kotlin的支持
17.9.1函数式Bean方式注册
17.9.2使用Kotlin调用Spring Web的功能性API
17.9.3 RestTemplate与函数式API扩展
17.9.4 Reactor的Kotlin扩展
17.9.5基于模板的Kotlin脚本
17.10 小结
第18章 使用Kotlin开发Android视频应用
18.1 项目概述
18.2 浅谈Android开发架构模式
18.2.1 MVC
18.2.2 MVP
18.2.3 MVVM
18.3 项目准备
18.3.1 新建Android项目
18.3.2添加项目库依赖
18.3.3编写主页面
18.3.4 GSYVideoPlayer播放器简介
18.4 功能开发
18.4.1 基础类封装
18.4.2 Retrofit封装
18.4.3 首页模块开发
18.4.4 视频详情页面开发
18.5 小结