是时候使用Kotlin编程了

  1. 云栖社区>
  2. 博客>
  3. 正文

是时候使用Kotlin编程了

code_xzh 2018-05-07 13:47:51 浏览1984
展开阅读全文

从事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 小结

网友评论

登录后评论
0/500
评论
code_xzh
+ 关注