描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787302505310
为便于读者快速掌握Kotlin编程方法,本书作者精心制作了电子书、完整的教学课件、完整的源代码与丰富的配套视频教程,并提供在线答疑服务。
推荐序 1
前言 3
配套资源说明 6
学习路线图 7
内容说明 9
第1篇 Kotlin基础
本篇视频:454分钟
第1章 开篇综述 2
本章视频:33分钟
1.1 Kotlin语言简介 2
1.1.1 Kotlin语言历史 2
1.1.2 Kotlin语言设计目标 2
1.2 Kotlin语言特点 3
1.3 Kotlin与Java虚拟机 4
1.3.1 Java虚拟机 4
1.3.2 Kotlin应用程序运行过程 5
1.4 如何获得帮助 5
第2章 开发环境搭建 8
本章视频:25分钟
2.1 JDK工具包 8
2.1.1 JDK下载和安装 8
2.1.2 设置环境变量 10
2.2 IntelliJ IDEA开发工具 12
2.3 Eclipse开发工具 13
2.3.1 Eclipse下载和安装 13
2.3.2 安装Kotlin插件 17
2.4 Kotlin编译器 18
2.4.1 下载Kotlin编译器 18
2.4.2 设置Kotlin编译器环境变量 19
2.5 文本编辑工具 20
2.5.1 在Sublime Text中安装Kotlin语言包 20
2.5.2 Sublime Text与Kotlin编译器集成 21
第3章 个Kotlin程序 25
本章视频:22分钟
3.1 使用REPL实现 25
3.2 使用IntelliJ IDEA实现 26
3.2.1 创建项目 26
3.2.2 创建Kotlin源代码文件 28
3.2.3 编写代码 29
3.2.4 运行程序 30
3.3 使用IntelliJ IDEA与Gradle实现 30
3.4 使用Eclipse与Kotlin插件实现 33
3.4.1 创建项目 33
3.4.2 创建Kotlin源代码文件 34
3.4.3 运行程序 35
3.5 使用文本编辑工具与Kotlin编译器实现 37
3.5.1 编写代码 37
3.5.2 编译程序 37
3.5.3 运行程序 39
3.6 代码解释 39
第4章 Kotlin语法基础 41
本章视频:52分钟
4.1 标识符和关键字 41
4.1.1 标识符 41
4.1.2 关键字 42
4.2 变量和常量 43
4.2.1 变量 43
4.2.2 常量和只读变量 44
4.2.3 使用var还是val 45
4.3 注释 46
4.4 语句与表达式 47
4.4.1 语句 48
4.4.2 表达式 48
4.5 包 49
4.5.1 包的作用 49
4.5.2 包的定义 50
4.5.3 包的引入 51
第5章 Kotlin编码规范 53
本章视频:49分钟
5.1 命名规范 53
5.2 注释规范 55
5.2.1 文件注释 55
5.2.2 文档注释 55
5.2.3 代码注释 58
5.2.4 使用地标注释 59
5.3 声明 60
5.3.1 变量或常量声明 60
5.3.2 类声明 61
5.4 代码排版 62
5.4.1 空行 62
5.4.2 空格 64
5.4.3 缩进 65
5.4.4 断行 65
5.5 省略规范 66
第6章 数据类型 68
本章视频:45分钟
6.1 回顾Java数据类型 68
6.2 Kotlin基本数据类型 69
6.2.1 整型类型 70
6.2.2 浮点类型 71
6.2.3 字符类型 72
6.2.4 布尔类型 74
6.3 数值类型之间的转换 75
6.3.1 赋值与显式转换 75
6.3.2 数学计算与隐式转换 77
6.4 可空类型 77
6.4.1 可空类型概念 78
6.4.2 使用安全调用运算符(?.) 78
6.4.3 非空断言运算符(!!) 79
6.4.4 使用Elvis运算符(?:) 80
第7章 字符串 82
本章视频:93分钟
7.1 字符串字面量 82
7.1.1 普通字符串 82
7.1.2 原始字符串 83
7.2 不可变字符串 85
7.2.1 String 85
7.2.2 字符串拼接 86
7.2.3 字符串模板 87
7.2.4 字符串查找 89
7.2.5 字符串比较 91
7.2.6 字符串截取 93
7.3 可变字符串 94
7.3.1 StringBuilder 94
7.3.2 字符串追加、插入、删除和替换 95
7.4 正则表达式 97
7.4.1 Regex类 97
7.4.2 字符串匹配 98
7.4.3 字符串查找 99
7.4.4 字符串替换 99
7.4.5 字符串分割 100
第8章 运算符 102
本章视频:51分钟
8.1 算术运算符 102
8.1.1 一元运算符 102
8.1.2 二元运算符 103
8.1.3 算术赋值运算符 104
8.2 关系运算符 105
8.3 逻辑运算符 107
8.4 位运算符 108
8.5 其他运算符 111
8.6 运算符优先级 111
第9章 程序流程控制 113
本章视频:47分钟
9.1 if分支结构 113
9.1.1 if结构当作语句使用 113
9.1.2 if表达式 115
9.2 when多分支结构 117
9.2.1 when结构当作语句使用 118
9.2.2 when表达式 119
9.3 循环结构 121
9.3.1 while语句 121
9.3.2 do-while语句 122
9.3.3 for语句 122
9.4 跳转语句 124
9.4.1 break语句 124
9.4.2 continue语句 126
9.5 使用区间 128
9.5.1 表示区间 128
9.5.2 使用in和!in关键字 129
第10章 函数 131
本章视频:37分钟
10.1 函数声明 131
10.2 返回特殊数据 132
10.2.1 无返回数据与Unit类型 132
10.2.2 永远不会正常返回数据与Nothing类型 133
10.3 函数参数 134
10.3.1 使用命名参数调用函数 134
10.3.2 参数默认值 135
10.3.3 可变参数 136
10.4 表达式函数体 137
10.5 局部函数 137
10.6 匿名函数 138
第2篇 面向对象
本篇视频:360分钟
第11章 面向对象编程 142
本章视频:246分钟
11.1 面向对象概述 142
11.2 面向对象的三个基本特性 143
11.2.1 封装性 143
11.2.2 继承性 143
11.2.3 多态性 144
11.3 类声明 144
11.4 属性 146
11.4.1 回顾JavaBean 146
11.4.2 声明属性 147
11.4.3 延迟初始化属性 150
11.4.4 委托属性 151
11.4.5 惰性加载属性 152
11.4.6 可观察属性 153
11.5 扩展 154
11.5.1 扩展函数 155
11.5.2 扩展属性 156
11.5.3 “成员优先”原则 157
11.5.4 定义中缀运算符 159
11.6 构造函数 160
11.6.1 主构造函数 160
11.6.2 次构造函数 162
11.6.3 默认构造函数 163
11.7 封装性与可见性修饰符 164
11.7.1 可见性范围 164
11.7.2 公有可见性 166
11.7.3 内部可见性 167
11.7.4 保护可见性 167
11.7.5 私有可见性 168
11.8 数据类 169
11.8.1 声明数据类 170
11.8.2 使用copy函数 171
11.8.3 解构数据类 172
11.9 枚举类 172
11.9.1 声明枚举类 172
11.9.2 枚举类构造函数 174
11.9.3 枚举常用属性和函数 175
11.10 嵌套类 176
11.10.1 嵌套类 176
11.10.2 内部类 178
11.11 强大的object关键字 180
11.11.1 对象表达式 180
11.11.2 对象声明 182
11.11.3 伴生对象 184
第12章 继承与多态 188
本章视频:78分钟
12.1 Kotlin中的继承 188
12.2 调用父类构造函数 190
12.2.1 使用主构造函数 191
12.2.2 使用次构造函数重载 192
12.2.3 使用参数默认值调用构造函数 193
12.3 重写成员属性和函数 194
12.3.1 重写成员属性 194
12.3.2 重写成员函数 195
12.4 多态 197
12.4.1 多态概念 197
12.4.2 使用is和!is进行类型检查 199
12.4.3 使用as和as?进行类型转换 202
12.5 密封类 203
第13章 抽象类与接口 206
本章视频:36分钟
13.1 抽象类 206
13.1.1 抽象类概念 206
13.1.2 抽象类声明和实现 206
13.2 使用接口 209
13.2.1 接口概念 209
13.2.2 接口声明和实现 209
13.2.3 接口与多继承 212
13.2.4 接口继承 213
13.2.5 接口中的具体函数和属性 214
第3篇 函数式编程
本篇视频:302分钟
第14章 函数式编程基石——高阶函数和Lambda表达式 218
本章视频:91分钟
14.1 函数式编程简介 218
14.2 高阶函数 218
14.2.1 函数类型 219
14.2.2 函数字面量 220
14.2.3 函数作为另一个函数返回值使用 221
14.2.4 函数作为参数使用 222
14.3 Lambda表达式 223
14.3.1 Lambda表达式标准语法格式 223
14.3.2 使用Lambda表达式 225
14.3.3 Lambda表达式简化写法 225
14.3.4 Lambda表达式与return语句 228
14.4 闭包与捕获变量 229
14.5 内联函数 232
14.5.1 自定义内联函数 232
14.5.2 使用let函数 233
14.5.3 使用with和apply函数 233
第15章 泛型 236
本章视频:51分钟
15.1 泛型函数 236
15.1.1 声明泛型函数 236
15.1.2 多类型参数 237
15.1.3 泛型约束 237
15.1.4 可空类型参数 238
15.2 泛型属性 239
15.3 泛型类 240
15.4 泛型接口 242
第16章 数据容器——数组和集合 245
本章视频:81分钟
16.1 数组 245
16.1.1 对象数组 245
16.1.2 基本数据类型数组 248
16.2 集合概述 249
16.3 Set集合 250
16.3.1 不可变Set集合 250
16.3.2 可变Set集合 252
16.4 List集合 254
16.4.1 不可变List集合 255
16.4.2 可变List集合 256
16.5 Map集合 258
16.5.1 不可变Map集合 259
16.5.2 可变Map集合 261
第17章 Kotlin中函数式编程API 264
本章视频:79分钟
17.1 函数式编程API与链式调用 264
17.2 遍历操作 265
17.2.1 forEach 265
17.2.2 forEachIndexed 266
17.3 三大基础函数 267
17.3.1 filter 267
17.3.2 map 268
17.3.3 reduce 269
17.4 聚合函数 270
17.5 过滤函数 272
17.6 映射函数 273
17.7 排序函数 275
17.8 案例:求阶乘 276
17.9 案例:计算水仙花数 277
第4篇 Kotlin进阶
本篇视频:744分钟
第18章 异常处理 280
本章视频:67分钟
18.1 从一个问题开始 280
18.2 异常类继承层次 281
18.2.1 Throwable类 281
18.2.2 Error和Exception 283
18.3 捕获异常 283
18.3.1 try-catch语句 284
18.3.2 try-catch表达式 285
18.3.3 多catch代码块 286
18.3.4 try-catch语句嵌套 288
18.4 释放资源 289
18.4.1 finally代码块 290
18.4.2 自动资源管理 293
18.5 throw与显式抛出异常 294
第19章 线程 297
本章视频:49分钟
19.1 基础知识 297
19.1.1 进程 297
19.1.2 线程 297
19.1.3 主线程 298
19.2 创建线程 299
19.3 线程状态 301
19.4 线程管理 302
19.4.1 等待线程结束 302
19.4.2 线程让步 304
19.4.3 线程停止 305
第20章 协程 308
本章视频:57分钟
20.1 协程介绍 308
20.2 创建协程 308
20.2.1 Kotlin协程API 308
20.2.2 创建支持kotlinx.coroutines的项目 309
20.2.3 个协程程序 310
20.2.4 launch函数与Job对象 311
20.2.5 runBlocking函数 313
20.2.6 挂起函数 314
20.3 协程生命周期 316
20.4 管理协程 317
20.4.1 等待协程结束 317
20.4.2 超时设置 318
20.4.3 取消协程 320
第21章 Kotlin与Java混合编程 322
本章视频:77分钟
21.1 数据类型映射 322
21.1.1 Java基本数据类型与Kotlin数据类型映射 322
21.1.2 Java包装类与Kotlin数据类型映射 322
21.1.3 Java常用类与Kotlin数据类型映射 323
21.1.4 Java集合类型与Kotlin数据类型映射 323
21.2 Kotlin调用Java 324
21.2.1 避免Kotlin关键字 324
21.2.2 平台类型与空值 325
21.2.3 异常检查 327
21.2.4 调用Java函数式接口 327
21.3 Java调用Kotlin 328
21.3.1 访问Kotlin属性 329
21.3.2 访问包级别成员 329
21.3.3 实例字段、静态字段和静态函数 330
21.3.4 可见性 334
21.3.5 生成重载函数 336
21.3.6 异常检查 338
第22章 Kotlin I/O与文件管理 340
本章视频:49分钟
22.1 Java I/O流概述 340
22.1.1 Java流设计理念 340
22.1.2 Java流类继承层次 341
22.2 字节流 343
22.2.1 InputStream抽象类 344
22.2.2 OutputStream抽象类 344
22.2.3 案例:文件复制 345
22.3 字符流 346
22.3.1 Reader抽象类 346
22.3.2 Writer抽象类 346
22.3.3 案例:文件复制 347
22.4 文件管理 348
22.4.1 File类扩展函数 348
22.4.2 案例:读取目录文件 349
第23章 网络编程 351
本章视频:115分钟
23.1 网络基础 351
23.1.1 网络结构 351
23.1.2 TCP/IP协议 352
23.1.3 IP地址 352
23.1.4 端口 353
23.2 TCP Socket低层次网络编程 353
23.2.1 TCP Socket通信概述 353
23.2.2 TCP Socket通信过程 353
23.2.3 Socket类 354
23.2.4 ServerSocket类 356
23.2.5 案例:文件上传工具 356
23.3 UDP Socket低层次网络编程 358
23.3.1 DatagramSocket类 358
23.3.2 DatagramPacket类 359
23.3.3 案例:文件上传工具 360
23.4 数据交换格式 362
23.4.1 JSON文档结构 363
23.4.2 使用第三方JSON库 365
23.4.3 JSON数据编码和解码 366
23.5 访问互联网资源 368
23.5.1 URL的概念 368
23.5.2 HTTP/HTTPS协议 369
23.5.3 使用URL类 369
23.5.4 使用HttpURLConnection发送GET请求 370
23.5.5 使用HttpURLConnection发送POST请求 372
23.5.6 实例:Downloader 373
第24章 Kotlin与Java Swing图形用户界面编程 375
本章视频:182分钟
24.1 Java图形用户界面技术 375
24.2 Swing技术基础 376
24.2.1 Swing类层次结构 377
24.2.2 Swing程序结构 378
24.3 事件处理模型 381
24.3.1 内部类和对象表达式处理事件 382
24.3.2 Lambda表达式处理事件 384
24.3.3 使用适配器 385
24.4 布局管理 387
24.4.1 FlowLayout布局 387
24.4.2 BorderLayout布局 389
24.4.3 GridLayout布局 391
24.4.4 不使用布局管理器 393
24.5 Swing组件 395
24.5.1 标签和按钮 395
24.5.2 文本输入组件 398
24.5.3 复选框和单选按钮 401
24.5.4 下拉列表 404
24.5.5 列表 406
24.5.6 分隔面板 407
24.5.7 使用表格 409
24.6 案例:图书库存 413
第25章 轻量级SQL框架—— Exposed 418
本章视频:91分钟
25.1 MySQL数据库管理系统 418
25.1.1 数据库安装与配置 418
25.1.2 连接MySQL服务器 422
25.1.3 常见的管理命令 425
25.2 Kotlin与DSL语言 429
25.3 使用Exposed框架 430
25.3.1 配置项目 430
25.3.2 面向DSL API 431
25.3.3 面向对象API 434
25.4 案例:多表连接查询操作 436
25.4.1 创建数据库 437
25.4.2 配置SQL日志 438
25.4.3 实现查询 438
第26章 反射 442
本章视频:34分钟
26.1 Kotlin反射API 442
26.2 引用类 443
26.3 调用函数 445
26.4 调用构造函数 446
26.5 调用属性 448
第27章 注解 451
本章视频:23分钟
27.1 元注解 451
27.2 自定义注解 453
27.2.1 声明注解 453
27.2.2 案例:使用元注解 454
27.2.3 注解目标声明 456
27.2.4 案例:读取运行时注解信息 457
第5篇 项目实战
本篇视频:621分钟
第28章 项目实战1:开发PetStore宠物商店项目 460
本章视频:309分钟
28.1 系统分析与设计 460
28.1.1 项目概述 460
28.1.2 需求分析 461
28.1.3 原型设计 461
28.1.4 数据库设计 463
28.1.5 架构设计 465
28.1.6 系统设计 466
28.2 任务1:创建数据库 467
28.2.1 迭代1.1:安装和配置MySQL数据库 467
28.2.2 迭代1.2:编写数据库DDL脚本 467
28.2.3 迭代1.3:插入初始数据到数据库 468
28.3 任务2:初始化项目 469
28.3.1 迭代2.1:配置项目 469
28.3.2 迭代2.2:添加资源图片 470
28.3.3 迭代2.3:添加包 471
28.4 任务3:编写数据持久层代码 471
28.4.1 迭代3.1:编写实体类 471
28.4.2 迭代3.2:创建数据表类 474
28.4.3 迭代3.3:编写DAO类 475
28.5 任务4:编写表示层代码 483
28.5.1 迭代4.1:编写启动类 483
28.5.2 迭代4.2:编写自定义窗口类——MyFrame 483
28.5.3 迭代4.3:用户登录窗口 485
28.5.4 迭代4.4:商品列表窗口 487
28.5.5 迭代4.5:商品购物车窗口 495
28.6 任务5:应用程序打包发布 503
28.6.1 迭代5.1:处理TODO和FIXME任务 503
28.6.2 迭代5.2:打包 503
第29章 项目实战2:开发Kotlin版QQ2006聊天工具 507
本章视频:312分钟
29.1 系统分析与设计 507
29.1.1 项目概述 507
29.1.2 需求分析 508
29.1.3 原型设计 509
29.1.4 数据库设计 509
29.1.5 网络拓扑图 512
29.1.6 系统设计 512
29.2 任务1:创建服务器端数据库 513
29.2.1 迭代1.1:安装和配置MySQL数据库 513
29.2.2 迭代1.2:编写数据库DDL脚本 514
29.2.3 迭代1.3:插入初始数据到数据库 514
29.3 任务2:初始化项目 515
29.3.1 任务2.1:配置项目 515
29.3.2 任务2.2:添加资源图片 516
29.3.3 任务2.3:添加包 517
29.4 任务3:编写服务器端外围代码 517
29.4.1 任务3.1:创建数据表类 517
29.4.2 任务3.2:编写UserDAO类 518
29.4.3 任务3.3:编写ClientInfo类 521
29.5 任务4:客户端UI实现 521
29.5.1 迭代4.1:登录窗口实现 521
29.5.2 迭代4.2:好友列表窗口实现 525
29.5.3 迭代4.3:聊天窗口实现 529
29.6 任务5:用户登录过程实现 533
29.6.1 迭代5.1:客户端启动 533
29.6.2 迭代5.2:客户端登录编程 535
29.6.3 迭代5.3:服务器启动 538
29.6.4 迭代5.4:服务器验证编程 539
29.7 任务6:刷新好友列表 541
29.7.1 迭代6.1:刷新好友列表服务器端编程 542
29.7.2 迭代6.2:刷新好友列表客户端编程 543
29.8 任务7:聊天过程实现 547
29.8.1 迭代7.1:客户端用户1向用户3发送消息 548
29.8.2 迭代7.2:服务器接收用户1消息与转发给用户3消息 549
29.8.3 迭代7.3:客户端用户3接收用户1消息 551
29.9 任务8:用户下线 552
29.9.1 迭代8.1:客户端编程 553
29.9.2 迭代8.2:服务器端编程 554
2017年5月19日的Google I/O大会上,谷歌公司宣布将Kotlin语言作为Android应用开发一级语言。国内很快掀起了学习Kotlin的热潮,就像2014年苹果公司发布Swift语言一样,一夜之间出现了很多团队翻译官方文档、录制视频课程。听说了这个消息我非常激动,也想写一本Kotlin立体图书,包括电子书、配套视频、课件和答疑服务。经过了6个多月的专注写作和实践终成此书,6个月来放弃很多对家人的陪伴,感谢她们的理解和 宽容。
由于工作的原因,我在2015年就接触到Kotlin语言,被它的简洁理念深深吸引。我将以前用Java编写的QQ聊天工具用Kotlin语言重新编写,代码减少了30%。Kotlin语言的设计者们设计这门语言的目的是取代Java。诞生了20多年的Java虽然还是排名的语言,但仍被人诟病,现在从如下几个方面讨论一下。
1. 对函数式编程的支持
Java对函数式编程的支持不够及时和彻底,直到Java 8才开始支持函数式编程,但Java 8中并不支持函数类型,不能定义高阶函数;而Kotlin支持函数式编程。试比较以下代码:
//Java面向对象代码片段
String userId = (String) jsonObj.get
(“user_id”);
//从clientList集合中删除用户
for (ClientInfo info : clientList) {
if (info.getUserId().equals
(userId)) {
clientList.remove(info);
break;
}
}
//Kotlin函数式编程代码片段
val userId = jsonObject[“user_id”] as String
val clientInfo = clientList.first {
it.userId == userId
}
//从clientList集合中删除用户
clientList.remove(clientInfo)
从上述代码比较可见,函数式编程中不再需要那些for和if等流程控制语句,对于数据的处理更加简洁。函数式编程并不能完全取代面向对象编程,函数式编程擅长进行数据处理,如核心业务逻辑、算法实现等;而面向对象编程擅长构建UI界面编程、搭建系统架构等。
2. 异常处理的理念
Java把异常分为受检查异常和运行期异常,编译器强制要求必须捕获或抛出受检查异常。经过多年的实践,开发者发现即便是捕获了那些受检查异常,处理起来也力不从心。受检查异常会使得程序结构变得混乱,代码大量增加。而Kotlin把所有的异常都看作是运行期异常,编译器不会强制要求捕获或抛出任何异常,开发人员可以酌情考虑是否捕获和处理异常。
下面再比较一些代码:
//Java文件复制代码片段
try (FileInputStream fis = new
FileInputStream(“./TestDir/src.zip”);
BufferedInputStream bis = new
BufferedInputStream(fis);
FileOutputStream fos = new
FileOutputStream(“./TestDir/
subDir/src.zip”);
BufferedOutputStream bos = new
BufferedOutputStream(fos)) {
//准备一个缓冲区
byte[] buffer = new byte[1024];
//首先读取一次
int len = bis.read(buffer);
while (len != -1) {
//开始写入数据
bos.write(buffer, 0, len);
//再读取一次
len = bis.read(buffer);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//Kotlin函数式编程代码片段
FileInputStream(“./TestDir/src.zip”)
.use { fis ->
FileOutputStream(“./TestDir/subDir/
src.zip”).use { fos ->
//复制到输出流
fis.buffered().copyTo
(fos.buffered())
println(“复制完成”)
}
}
上述代码实现了文件复制,Java代码需要21行,而Kotlin代码只需要7行。
3. 对可空类型的支持
空指针异常是Java令人头痛的问题之一。Java数据类型可以接收空值;而Kotlin数据类型默认不能接收空值,是非空数据类型,这样就保证了数据类型的安全,防止空指针异常的发生。
这里只是比较了Java和Kotlin几个突出的区别,更多的不同和细微的差别还需要读者阅读此书,并自己编写其中的每一个示例,感受Kotlin与Java的不同,感受Kotlin的 简洁。
本书服务网址
为了更好地为广大读者提供服务,本书建立了一个服务网址www.zhijieketang/group/6,希望读者对书中内容发表评论,提出宝贵意见。
源代码
书中包括了200多个完整的案例项目源代码,读者可以到本书网站www.zhijieketang/ group/6免费注册下载。
勘误与支持
网站www.zhijieketang/group/6中建立了一个勘误专区,可以及时地把书中的问题、失误和勘误反馈给广大读者。如果读者发现了任何问题,均可以在网上留言,也可以发送电子邮件到[email protected],也可以通过作者的新浪微博(@tony_关东升)或微信(q270258799)联系作者与编辑。
致谢
本书主要由关东升著。此外,智捷课堂团队的赵志荣、赵大羽、关锦华、闫婷娇、王馨然、关秀华、刘佳笑和赵浩丞参与了部分内容的编写。感谢清华大学出版社的盛东亮编辑给本书提供的宝贵意见。感谢赵浩丞手绘了书中全部草图,并从专业的角度修改书中图片,力求更加真实完美地奉献给广大读者。感谢我的家人容忍我的忙碌以及对我的关心和照顾,使我能抽出这么多时间,投入全部精力,专心编写此书。
由于时间仓促,书中难免存在不妥之处,请读者原谅,并提出宝贵意见。
关东升
2018年6月
个Kotlin程序
本章视频:22分钟
本章以HelloWorld作为切入点,介绍如何编写和运行Kotlin程序代码。
编写和运行Kotlin程序有多种方式,总的来说有两种:
(1)交互式方式运行;
(2)编译为字节码文件方式运行。
交互式方式运行可以采用REPL。编译为字节码方式运行就是使用IntelliJ IDEA或Eclipse创建一个项目,通过这些工具可以编译和运行Kotlin源文件。另外还可以使用文本编辑工具编写Kotlin源文件,再使用Kotlin编译器提供的kotlinc命令在命令提示行中编译Kotlin源程序,然后再通过kotlin命令或JDK提供的java命令运行。
本章介绍如何使用这些工具实现HelloWorld程序。
3.1 使用REPL实现
REPL是英文Read-Eval-Print Loop的缩写,直译为“读取-求值-输出”,它指代一种简单的交互式运行编程环境。REPL对于学习一门新的编程语言有很大的帮助,因为它能立刻对初学者做出回应。许多编程语言都可以使用REPL研究算法以及进行调试。
启动REPL可以通过Kotlin编译器提供的kotlinc命令或在IntelliJ IDEA工具中选择Tools→Kotlin→Kotlin REPL菜单。打开命令提示行输入kotlinc命令,如图3-1所示。启动REPL,Kotlin REPL提供一些前面带有冒号(:)的管理指令,例如“:quit”指令是退出REPL,“:help”指令是帮助。
在REPL窗口中可以输入Kotlin代码,按Enter键后马上会运行并输出结果,测试代码如下:
>>> 1 1 ①
2 ②
>>> val str = “Hello, world.” ③
>>> println(str) ④
Hello, world. ⑤
>>>
“>>>”后面是Kotlin代码,第①行、第③行和第④行都是代码,而第②行、第⑤行是运行结果。
图3-1 在命令提示行中启动REPL
3.2 使用IntelliJ IDEA实现
3.1节介绍了如何以交互式方式编写和运行Kotlin程序代码,交互式方式在很多情况下适合学习Kotlin语言,但是如果要使用Kotlin语言开发实际项目,交互式方式就不适合了。此时,需要创建项目,在项目中创建文件,编译文件,运行文件。
首先介绍如何使用IntelliJ IDEA创建Kotlin项目以编写和运行HelloWorld程序。
3.2.1 创建项目
首先在IntelliJ IDEA中通过项目(Project)管理Kotlin源代码文件,因此需要先创建一个Kotlin项目,然后在项目中创建一个Kotlin源代码文件。
IntelliJ IDEA创建项目步骤是:打开IntelliJ IDEA的欢迎界面(见图3-2),单击Create New Project打开如图3-3所示的对话框。一般次启动就可以看到这个界面,如果没有,也可以通过选择菜单File→New→Project命令来打开。
由于要编写的HelloWorld程序属于基于Java虚拟机的Kotlin项目,因此需要创建Kotlin/JVM类型项目,在图3-3中选择Java中的Kotlin/JVM(见图3-4(a))或者选择Kotlin中的Kotlin/JVM(见图3-4(b))都可以创建Kotlin/JVM类型项目。
图3-2 IntelliJ IDEA欢迎界面
图3-3 选择项目类型
(a)选择Java中的Kotlin/JVM (b)选择Kotlin中的Kotlin/JVM
图3-4 选择Kotlin/JVM类型项目
这里选择如图3-4(b)所示的界面Kotlin/JVM类型项目,然后单击Next按钮进入如图3-5所示的界面。在Project name中输入项目名,本例中是项目ch3.2,Project location中选择保存项目路径,选择合适的Project SDK后,单击Finish按钮创建项目,如图3-6所示。
图3-5 输入项目命名
图3-6 项目创建完成
3.2.2 创建Kotlin源代码文件
项目创建完成后,需要创建一个Kotlin源代码文件执行控制台输出操作。选择刚刚创建的项目,选中src文件夹,然后选择菜单File→New→Kotlin File/Class,打开新建Kotlin文件或类对话框,如图3-7所示,在对话框中的Name文本框中输入HelloWorld,Kind(类型)下拉框中选择File(文件),然后单击OK按钮创建文件。如图3-8所示,在左边的项目文件管理窗口中可以看到刚刚创建的HelloWorld.kt源代码文件。
图3-7 新建Kotlin文件或类
图3-8 HelloWorld.kt源代码文件
3.2.3 编写代码
要想让Kotlin源代码文件能够运行起来,需要使用main函数。main函数是程序的入口,它与C 语言中的main函数类似,都不属于任何的类,称为顶层函数(top-level function)。但是与Java不同,Java中程序的入口也是main函数,但Java中所有的函数都必须在某个类中定义,main函数也不例外。
编写代码如下:
fun main(args: Array) {
println(“Hello, world!”)
}
如果是Java,实现同样功能的代码如下:
public class HelloWorld {
public static void main(String[] args) {
System.out.print(“Hello, world!”);
}
}
3.2.4 运行程序
程序编写完成就可以运行了。如果是次运行,则需要右击左边的项目文件管理窗口中的HelloWorld.kt文件,在弹出的菜单中选择Run ‘HelloWorldKt’运行,运行结果如图3-9所示,在左下面的控制台窗口输出“Hello, world!”字符串。
图3-9 运行结果
注意
如果已经运行过一次,也可直接单击工具栏中的Run 按钮,或选择菜单Run→Run ‘HelloWorldKt’,或使用快捷键Ctrl F10,就可以运行上次的程序。
3.3 使用IntelliJ IDEA与Gradle实现
Gradle是一个基于Apache Ant和Apache Maven的项目自动化建构工具。它不是用传统的XML语言描述的,而是使用一种基于Groovy的特定领域语言(DSL)来描述的。IntelliJ IDEA工具内置对Gradle的支持,可以通过IntelliJ IDEA与Gradle构建Java和Kotlin项目。
在IntelliJ IDEA中创建Gradle与Kotlin/JVM的项目步骤与创建Kotlin/JVM项目类似,首先参考3.2.1节,打开如图3-3所示的选择项目类型对话框,选择Gradle中的Kotlin(Java),如图3-10所示。
图3-10 选择Kotlin/JVM类型项目
在图3-10所示的界面中,单击Next按钮进入Gradle配置项目名称对话框,在各个项目中输入相应内容,如图3-11所示,其中GroupId是公司或组织的域名倒置;ArtifactId是项目名称,GroupId可以省略,但是ArtifactId不能省略;Version是该项目的版本号,用于自己的项目版本管理。
图3-11 Gradle配置项目名称
在图3-11所示界面中,单击Next按钮进入Gradle项目配置对话框,如图3-12所示,其中各个选项说明如下:
* Use auto-import。是否开启自动导入功能,如果开启,当修改Gradle脚本文件时,会自动检测变化并对项目进行刷新。
* Create separate module per source set。每个模块都有独立的源代码目录结构。
* Store generated project files externally。项目生成文件是否不进行版本管理。在IntelliJ IDEA项目中会有一些项目生成文件,如.ipr、.iml和.iws等文件。在团队开发时,往往会使用代码版本控制软件,这些文件是不应该提交服务器进行版本控制的。开启此项后,这些自动生成文件不会被提交服务器进行版本管理。
* Use default gradle wrapper (recommended)。使用默认的Gradle Wrapper,它会通过网络自动更新,这是推荐选项。
* Use local gradle distribution。使用本地的Gradle Wrapper,选择此项需要指定本地Gradle Wrapper的位置。
图3-12 配置Gradle项目
在图3-12所示的界面,单击Next按钮进入项目保存界面,输入文件名并选择保存文件路径,单击Finish按钮完成创建项目,如图3-13所示,其中项目下的/src/main目录是源代码根目录,一般而言main下面的java目录放置Java源代码,kotlin目录放置Kotlin源代码文件,resource放置资源文件(图片、声音和配置等文件)。
图3-13 项目创建完成
IntelliJ IDEA与Gradle项目编写代码和运行程序与IntelliJ IDEA项目没有区别,这里不再赘述。
3.4 使用Eclipse与Kotlin插件实现
本节介绍如何通过Eclipse与Kotlin插件实现编写和运行HelloWorld程序。
3.4.1 创建项目
在Eclipse中也是通过项目管理Kotlin源代码文件的,因此需要先创建一个Kotlin项目,然后在项目中创建一个Kotlin源代码文件。
Eclipse创建项目的步骤是:打开Eclipse,选择菜单File→New→Project,打开选择项目向导对话框,如图3-14所示,选择Kotlin下面的Kotlin Project。单击Next按钮,进入如图3-15所示的对话框,在这里可以输入项目名和保存项目,输入完成后,单击Finish按钮创建项目。项目创建完成后,回到如图3-16所示的Eclipse主界面。
图3-14 选择项目向导对话框
图3-15 输入项目名和保存项目
图3-16 项目创建完成
3.4.2 创建Kotlin源代码文件
项目创建完成后,需要创建一个Kotlin源代码文件执行控制台输出操作。选择刚刚创建的项目,选中项目中的src文件夹,然后选择菜单File →New→Other,打开创建文件向导对话框,如图3-17所示,选择Kotlin下面的Kotlin File。单击Next按钮,进入如图3-18所示的保存文件对话框,其中Source folder文本框是文件保存文件夹,默认是src文件夹;Package文本框保存该文件所在的包,有关包的概念将在第4章详细介绍。在Name文本框输入文件名,输入完成后,单击Finish按钮创建文件,文件创建完成后,回到如图3-19所示的Eclipse主界面。
图3-17 选择创建文件向导对话框
图3-18 保存文件
图3-19 文件创建完成
3.4.3 运行程序
修改刚刚生成的HelloWorld.kt源文件,代码如图3-20所示。
程序编写完成就可以运行了。如果是次运行,则需要选择运行方法,具体步骤是:选中文件,选择菜单Run→Run As→Kotlin Application,这样就会运行HelloWorld程序了。如果已经运行过一次,就不需要这么麻烦了,直接单击工具栏中的Run按钮,或选择菜单Run→Run,或使用快捷键Ctrl F10,就可以运行上次的程序了。运行结果如图3-21所示,下面的控制台输出“Hello, world!”字符串。
图3-20 修改HelloWorld.kt源文件
图3-21 运行结果
3.5 使用文本编辑工具与Kotlin编译器实现
如果不想使用IDE工具(笔者建议初学者通过这种方式学习Kotlin),那么文本编辑工具与Kotlin编译器对于初学者而言是一个不错的选择,这种方式可以使初学者了解到Kotlin程序的编译和运行过程,通过在编辑器中输入所有代码,可以帮助读者熟悉常用函数和类,能快速掌握Kotlin语法。
注意
在2.5.2节已介绍过Sublime Text与Kotlin编译器的集成过程,但本节介绍的编译和运行过程完全是手动的,这样可以帮助读者了解Kotlin程序的编译和运行过程。
3.5.1 编写代码
首先使用任意文本编辑工具创建一个文件,然后将文件保存为HelloWorld.kt。接着在HelloWorld.kt文件中编写如下代码:
fun main(args: Array) {
println(“Hello, world!”)
}
3.5.2 编译程序
编译程序需要在命令行中使用Kotlin编译器的kotlinc指令编译,打开命令行,进入源文件所在的目录,然后执行如下指令:
kotlinc HelloWorld.kt
如果没有错误提示,则说明编译成功。编译成功后会在当前目录下面生成HelloWorldKt.class字节码文件,如图3-22所示。
另外,为了方便运行和管理,往往会将Kotlin字节码文件和Kotlin运行时库打包成一个独立的jar文件,需要执行如下指令:
kotlinc HelloWorld.kt -include-runtime -d HelloWorld.jar
图3-22 编译源文件
其中,-include-runtime参数是设置jar文件中包含Kotlin运行时库,-d参数是指定编译结果输出目的地,这个目的地可以是目录或jar打包文件。编译成功后会在当前目录下生成HelloWorld.jar打包文件,如图3-23所示。打开HelloWorld.jar文件,如图3-24所示,kotlin和org两个文件夹实际上就是Kotlin的运行时库,META-INF文件夹是jar打包时生成的,用来存放包中文件清单等信息。
图3-23 编译并打包jar文件
提示
一般在发布java字节码文件时,会把字节码文件(class文件)打包成jar文件。jar文件是一种基于zip结构的压缩文件,可以使用JDK中的jar命令解压,或是使用任何支持解压zip格式的软件打开或解压。如图3-24所示是使用7z(http://www.7-zip.org)软件打开的界面。使用jar文件有很多好处,首先文件是经过压缩的,占用空间小,其次是多个文件(字节码、资源和配置文件)被打包成一个文件方便管理。
图3-24 使用7z软件打开jar文件
3.5.3 运行程序
3.3.2节编译的结果可能是Kotlin字节码文件或包含Kotlin运行时库的jar文件。这两种不同的文件运行方式不同,但本质上都是使用java命令运行的。
1. 运行Kotlin字节码文件
运行Kotlin字节码文件简单的方式是使用Kotlin编译器提供的kotlin命令,指令如下:
kotlin HelloWorldKt
运行过程如图3-25所示。
2. 运行包含Kotlin运行时库的jar文件
运行包含Kotlin运行时库的jar文件,需要使用指令如下:
java -jar HelloWorld.jar
运行过程如图3-26所示。
图3-25 Kotlin命令运行字节码文件 图3-26 运行包含Kotlin运行时库的jar文件
3.6 代码解释
至此只是介绍了如何编写、编译和运行HelloWorld程序,还没有对如下的HelloWorld代码进行解释:
fun main(args: Array) { ①
println(“Hello, world!”) ②
}
从代码中可见,Kotlin实现HelloWorld的方式比Java、C和C 等语言要简单得多,下面详细解释一下代码。
代码第①行的fun 关键字是声明一个函数,main是函数名,args 是参数;Array是参数类型,该类型是字符串数组类型。代码第②行是println函数,作用是在控制台输出字符串,并且后面跟有一个换行符。类似还有print函数,该函数后面没有换行符。
提示
Kotlin中有一些函数不属于任何类,这些函数是顶层函数。上述示例中println函数对应Java中System.out.println函数,print函数对应Java中System.out.print函数。
本章小结
本章通过一个HelloWorld示例,介绍使用IntelliJ IDEA、IntelliJ IDEA与Gradle工具实现该示例的具体过程。此外,还介绍了利用其他一些工具,如Eclipse与Kotlin、文本编辑器与Kotlin编译器的实现过程。
评论
还没有评论。