第 1 部分 Kotlin 简介 1
1 Kotlin :定义和目的 3
1.1 Kotlin 初体验 3
1.2 Kotlin 的主要特征4
1.2.1 目标平台 :服务器端、Android 及任何 Java 运行的地方 4
1.2.2 静态类型5
1.2.3 函数式和面向对象 6
1.2.4 免费并开源 7
1.3 Kotlin 应用8
1.3.1 服务器端的 Kotlin8
1.3.2 Android 上的 Kotlin 9
1.4 Kotlin 的设计哲学 10
1.4.1 务实10
1.4.2 简洁 11
1.4.3 安全12
1.4.4 互操作性 13
1.5 使用 Kotlin 工具 14
1.5.1 编译 Kotlin 代码 14
1.5.2 IntelliJ IDEA 和 Android Studio 插件 15
1.5.3 交互式 shell15
1.5.4 Eclipse 插件 15
1.5.5 在线 playground 15
1.5.6 Java 到 Kotlin 的转换器 16
1.6 小结16
2 Kotlin 基础 17
2.1 基本要素 :函数和变量 17
2.1.1 Hello,world!18
2.1.2 函数18
2.1.3 变量20
2.1.4 更简单的字符串格式化 :字符串模板 22
2.2 类和属性 23
2.2.1 属性24
2.2.2 自定义访问器 25
2.2.3 Kotlin 源码布局 :目录和包26
2.3 表示和处理选择 :枚举和“when” 28
2.3.1 声明枚举类28
2.3.2 使用“when”处理枚举类 29
2.3.3 在“when”结构中使用任意对象 30
2.3.4 使用不带参数的“when” 31
2.3.5 智能转换 :合并类型检查和转换32
2.3.6 重构 :用“when”代替“if” 34
2.3.7 代码块作为“if”和“when”的分支 35
2.4 迭代事物 :“while”循环和“for”循环 36
2.4.1 “while”循环36
2.4.2 迭代数字 :区间和数列 37
2.4.3 迭代 map 38
2.4.4 使用“in”检查集合和区间的成员39
2.5 Kotlin 中的异常 41
2.5.1 “try”“catch”和“finally” 41
2.5.2 “try”作为表达式 42
2.6 小结44
3 函数的定义与调用 45
3.1 在 Kotlin 中创建集合 45
3.2 让函数更好调用 47
3.2.1 命名参数 48
3.2.2 默认参数值49
3.2.3 消除静态工具类 :顶层函数和属性 50
3.3 给别人的类添加方法 :扩展函数和属性53
3.3.1 导入和扩展函数 54
3.3.2 从 Java 中调用扩展函数54
3.3.3 作为扩展函数的工具函数55
3.3.4 不可重写的扩展函数 56
3.3.5 扩展属性 58
3.4 处理集合 :可变参数、中缀调用和库的支持 59
3.4.1 扩展 Java 集合的 API 59
3.4.2 可变参数 :让函数支持任意数量的参数60
3.4.3 键值对的处理 :中缀调用和解构声明 60
3.5 字符串和正则表达式的处理 62
3.5.1 分割字符串62
3.5.2 正则表达式和三重引号的字符串63
3.5.3 多行三重引号的字符串 64
3.6 让你的代码更整洁 :局部函数和扩展 66
3.7 小结68
4 类、对象和接口 69
4.1 定义类继承结构 70
4.1.1 Kotlin 中的接口 70
4.1.2 open、final 和 abstract 修饰符 :默认为 final72
4.1.3 可见性修饰符 :默认为 public 75
4.1.4 内部类和嵌套类 :默认是嵌套类76
4.1.5 密封类 :定义受限的类继承结构79
4.2 声明一个带非默认构造方法或属性的类80
4.2.1 初始化类 :主构造方法和初始化语句块80
4.2.2 构造方法 :用不同的方式来初始化父类83
4.2.3 实现在接口中声明的属性85
4.2.4 通过 getter 或 setter 访问支持字段 87
4.2.5 修改访问器的可见性 88
4.3 编译器生成的方法 :数据类和类委托 89
4.3.1 通用对象方法 89
4.3.2 数据类 :自动生成通用方法的实现 92
4.3.3 类委托 :使用“by”关键字 93
4.4 “object”关键字 :将声明一个类与创建一个实例结合起来95
4.4.1 对象声明 :创建单例易如反掌 95
4.4.2 伴生对象 :工厂方法和静态成员的地盘98
4.4.3 作为普通对象使用的伴生对象 100
4.4.4 对象表达式 :改变写法的匿名内部类 102
4.5 小结 104
5 Lambda 编程 105
5.1 Lambda 表达式和成员引用 105
5.1.1 Lambda 简介 :作为函数参数的代码块106
5.1.2 Lambda 和集合 107
5.1.3 Lambda 表达式的语法 108
5.1.4 在作用域中访问变量 111
5.1.5 成员引用 114
5.2 集合的函数式 API 116
5.2.1 基础 :filter 和 map 116
5.2.2 “all”“any”“count”和“find”: 对集合应用判断式 118
5.2.3 groupBy :把列表转换成分组的 map 119
5.2.4 flatMap 和 flatten :处理嵌套集合中的元素120
5.3 惰性集合操作 :序列121
5.3.1 执行序列操作 :中间和末端操作 123
5.3.2 创建序列 125
5.4 使用 Java 函数式接口 126
5.4.1 把 lambda 当作参数传递给 Java 方法127
5.4.2 SAM 构造方法 :显式地把 lambda 转换成函数式接口 129
5.5 带接收者的 lambda :“with”与“apply”131
5.5.1 “with”函数131
5.5.2 “apply”函数 133
5.6 小结 135
6 Kotlin 的类型系统137
6.1 可空性137
6.1.1 可空类型 138
6.1.2 类型的含义 140
6.1.3 安全调用运算符 :“?:”141
6.1.4 Elvis 运算符 :“?:” 143
6.1.5 安全转换 :“as?” 145
6.1.6 非空断言 :“!!”146
6.1.7 “let”函数148
6.1.8 延迟初始化的属性 149
6.1.9 可空类性的扩展 151
6.1.10 类型参数的可空性 153
6.1.11 可空性和 Java 153
6.2 基本数据类型和其他基本类型 157
6.2.1 基本数据类型 :Int、Boolean 及其他158
6.2.2 可空的基本数据类型 :Int?、Boolean? 及其他159
6.2.3 数字转换 160
6.2.4 “Any”和“Any?”:根类型 162
6.2.5 Unit 类型 :Kotlin 的“void”163
6.2.6 Nothing 类型 :“这个函数永不返回” 164
6.3 集合与数组 164
6.3.1 可空性和集合165
6.3.2 只读集合与可变集合167
6.3.3 Kotlin 集合和 Java 168
6.3.4 作为平台类型的集合171
6.3.5 对象和基本数据类型的数组173
6.4 小结 175
第 2 部分 拥抱 Kotlin 177
7 运算符重载及其他约定179
7.1 重载算术运算符 180
7.1.1 重载二元算术运算 180
7.1.2 重载复合赋值运算符183
7.1.3 重载一元运算符 184
7.2 重载比较运算符 186
7.2.1 等号运算符 :“equals" 186
7.2.2 排序运算符 :compareTo187
7.3 集合与区间的约定 188
7.3.1 通过下标来访问元素 :“get”和“set” 188
7.3.2 “in”的约定190
7.3.3 rangeTo 的约定 191
7.3.4 在“for”循环中使用“iterator”的约定 192
7.4 解构声明和组件函数193
7.4.1 解构声明和循环 194
7.5 重用属性访问的逻辑 :委托属性 195
7.5.1 委托属性的基本操作196
7.5.2 使用委托属性 :惰性初始化和“by lazy()”197
7.5.3 实现委托属性198
7.5.4 委托属性的变换规则202
7.5.5 在 map 中保存属性值 203
7.5.6 框架中的委托属性 204
7.6 小结 205
8 高阶函数 :Lambda 作为形参和返回值 207
8.1 声明高阶函数207
8.1.1 函数类型 208
8.1.2 调用作为参数的函数209
8.1.3 在 Java 中使用函数类 211
8.1.4 函数类型的参数默认值和 null 值 212
8.1.5 返回函数的函数 214
8.1.6 通过 lambda 去除重复代码 216
8.2 内联函数 :消除 lambda 带来的运行时开销218
8.2.1 内联函数如何运作 219
8.2.2 内联函数的限制 221
8.2.3 内联集合操作222
8.2.4 决定何时将函数声明成内联223
8.2.5 使用内联 lambda 管理资源 223
8.3 高阶函数中的控制流225
8.3.1 lambda 中的返回语句 :从一个封闭的函数返回225
8.3.2 从 lambda 返回 :使用标签返回226
8.3.3 匿名函数 :默认使用局部返回 228
8.4 小结 229
9 泛型 231
9.1 泛型类型参数232
9.1.1 泛型函数和属性 232
9.1.2 声明泛型类 234
9.1.3 类型参数约束235
9.1.4 让类型形参非空 237
9.2 运行时的泛型 :擦除和实化类型参数 238
9.2.1 运行时的泛型 :类型检查和转换 238
9.2.2 声明带实化类型参数的函数241
9.2.3 使用实化类型参数代替类引用 243
9.2.4 实化类型参数的限制244
9.3 变型 :泛型和子类型化 245
9.3.1 为什么存在变型 :给函数传递实参245
9.3.2 类、类型和子类型 246
9.3.3 协变 :保留子类型化关系 248
9.3.4 逆变 :反转子类型化关系 252
9.3.5 使用点变型 :在类型出现的地方指定变型254
9.3.6 星号投影 :使用 * 代替类型参数 257
9.4 小结 261
10 注解与反射 263
10.1 声明并应用注解264
10.1.1 应用注解264
10.1.2 注解目标265
10.1.3 使用注解定制 JSON 序列化 267
10.1.4 声明注解269
10.1.5 元注解 :控制如何处理一个注解 270
10.1.6 使用类做注解参数 271
10.1.7 使用泛型类做注解参数272
10.2 反射 :在运行时对 Kotlin 对象进行自省 273
10.2.1 Kotlin 反射 API :KClass、KCallable、KFunction 和KProperty 274
10.2.2 用反射实现对象序列化278
10.2.3 用注解定制序列化 279
10.2.4 JSON 解析和对象反序列化283
10.2.5 反序列化的最后一步 :callBy() 和使用反射创建对象 287
10.3 小结 291
11 DSL 构建 293
11.1 从 API 到 DSL 293
11.1.1 领域特定语言的概念 295
11.1.2 内部 DSL296
11.1.3 DSL 的结构 297
11.1.4 使用内部 DSL 构建 HTML298
11.2 构建结构化的 API:DSL 中带接收者的 lambda 299
11.2.1 带接收者的 lambda 和扩展函数类型 299
11.2.2 在 HTML 构建器中使用带接收者的 lambda 303
11.2.3 Kotlin 构建器 :促成抽象和重用307
11.3 使用“invoke”约定构建更灵活的代码块嵌套 310
11.3.1 “invoke”约定 :像函数一样可以调用的对象 310
11.3.2 “invoke”约定和函数式类型 311
11.3.3 DSL 中的“invoke”约定 :在 Gradle 中声明依赖 312
11.4 实践中的 Kotlin DSL 314
11.4.1 把中缀调用链接起来 :测试框架中的“should” 314
11.4.2 在基本数据类型上定义扩展 :处理日期 316
11.4.3 成员扩展函数 :为 SQL 设计的内部 DSL317
11.4.4 Anko :动态创建 Android UI 320
11.5 小结 322
A 构建 Kotlin 项目 323
B Kotlin 代码的文档化 327
C Kotlin 生态系统 331
· · · · · · (
收起)