第1章 Kotlin是什么java
当下互联网大数据云计算时代,数以百万计的应用程序在服务器、移动手机端上运行,其中的开发语言有很大一部分是用流行软件界20多年的、强大稳定的主力的编程语言Java编写。git
若是咱们用一辆汽车来比喻编程语言的话,Java 拥有一个快速、可靠的发动机,但防抱死刹车系统,动力转向系统却不是那么地彻底可控。驾驶起来得当心翼翼地检查可能出现的空指针,处理检查异常,重复生成冗长而单调的样板代码行等等。而编程语言的防危性(safety)和安全性(security)却又是相当重要的。程序员
要是有一门语言,既能继承Java的全部优势特性及其背后强大完备的生态库,又能更加简单、安全可控,那真是再好不过了。github
咱们很高兴地看到,Kotlin就是这样一门语言。Kotlin是一门非研究性的语言,它是一门很是务实的工业级编程语言,它的使命就是帮助程序员们解决实际工程实践中的问题。使用Kotlin 让 Java程序员们的生活变得更好,Java中的那些空指针错误,浪费时间的冗长的样板代码,啰嗦的语法限制等等,在Kotlin中通通消失。Kotlin 简单务实,语法简洁而强大,安全且表达力强,极富生产力。算法
本章咱们先简单介绍Kotlin语言的发展历史和语言特性,而后简述为何要去学习Kotlin语言。最后,简要介绍JVM语言家族。编程
首先,Kotlin是一种基于JVM的静态类型编程语言。让咱们从Hello World开始。与 C/C ++/Java 同样,Kotlin 程序的入口点是一个名为“main”的函数,它传递一个包含任何命令行参数的数组。windows
package com.easy.kotlin fun main(args: Array<String>) { println("Hello,World!") }
上面的代码简单说明以下:数组
1.Kotlin中的包package的使用跟Java基本相同。浏览器
2.Kotlin 变量声明 args: Array<String> 相似于Pascal,先写变量名args,冒号隔开,再在后面写变量的类型Array<String> 。 安全
3.与Scala和Groovy同样 ,代码行末尾的分号是可选的。在大多数状况下, 编译器根据换行符就可以推断语句已经结束。
4.Kotlin中使用fun关键字声明函数(方法),充满乐趣的fun。
人们为何喜欢Kotlin?Kotlin为何值得咱们去学习?下面是一个不彻底的清单列表:
Kotlin的优点是,既有Java的完整生态(Kotlin 彻底无缝使用各种Java API框架库),又有现代语言的高级特性 (语法糖)。
Kotlin 语言的设计的初衷之一是为了 JetBrains 团队的内部使用,旨在帮助公司下降成本。用过IntelliJ IDEA的都知道JetBrains 团队出品,皆是良品。毫无疑问,Kotlin的设计是务实的 。发展和促进 Kotlin 的好处大于其成本, 在这个过程当中, Kotlin 已经演变成了一个 JetBrains 的效率工具。其强烈的务实取向强烈地吸引了一大批Java程序员。
Kotlin 也成为 JetBrains 工具生态系统中重要的一员。但愿在将来几年内 Kotlin 成为主要的非 Java的 JVM语言,甚至有一天成为下一个Java语言。能够预测的是,Kotlin 将大大提高整个Java 互联网开发者的效率和质量。
Kotlin语言的特性能够简单归纳以下:
1.实用主义( Pragmatic ):务实、注重工程实践性。咱们常常会听到或者看到人们说编程是数学,或者是工程,是艺术,是科学,这些说法都是颇有道理的。Kotlin是一门偏重工程实践与艺术上的极简风格的语言。
2.极简主义( Minimalist ):语法简洁优雅不啰嗦,类型系统中一切皆是引用(reference)。
3.空安全(Null Safety):有一个简单完备的类型系统来支持空安全
4.多范式 (multi-paradigm ):同时一等支持 OOP 与 FP 编程范式。各类编程风格的组合可让咱们更加直接地表达算法思想和解决问题的方案,能够赋予咱们思考上更大的自由度和灵活性。
5.可扩展:直接扩展类的函数与属性(extension functions & properties)。这与咱们在Java中常常写的util类是彻底不同的体验!Kotlin是一门很是注重用户体验的语言。
6.高阶函数与闭包(higher-order functions & closures)。Kotlin 的类型中,函数类型(function type)也是一等类型( first class type),在Kotlin中咱们能够把函数当成值进行传递。这直接赋予了 Kotlin 函数式编程的特性。
使用Kotin能够写出一些很是优雅的代码。
7.支持快速实现 DSL。有了扩展函数、闭包等特性的支持,使用Kotlin实现一个DSL将会至关简单方便。
“咱们认为Kotlin的定位是一种现代化工业语言:它专一于代码重用和可读性的弹性抽象,以及面向早期错误侦测,和明确捕获维护与清理的意图,这些问题的静态类型安全性。Kotlin最重要的使用场景之一是对于一个庞大的Java代码库,其开发者须要一个更棒的语言:你可以将Java和Kotlin自由混合,迁移能够是渐进式的,不须要一会儿对整个代码库进行改变。”
“Kotlin旨在成为一种面向工业的面向对象语言,并且是一种比Java更好的语言,但仍然能够与Java代码彻底互操做,容许企业逐步从Java迁移到Kotlin 。”
Andrey Breslav, Kotlin创始人
编程的真正的问题在于,如何把人类脑子里对问题的解决方案“具化”到机器世界,而这个“具化”的过程正是编程语言所要表达的东西。如何富有表现力而且安全简洁地表达,这是全部编程语言所要解决的问题。
Kotlin设计了一个“归一化”的类型系统(一切类型皆是引用类型),纯自然地设置了一道空指针的屏障,使得Kotlin比Java更加安全可靠。Kotlin还引入了类型推断、一等支持函数式编程、Lambda、高阶函数、类的扩展函数与属性、DSL等诸多特性,使得咱们能够编写简单、优雅且高效的代码,更加专一地投入在业务逻辑的实现上。
优秀的程序员固然会选择使用Kotlin这些更加先进的特性,由于它们毫无疑问有助于更直接地表达观点,并且也没有额外的开销。何乐而不为呢?
“工欲善其事必先利其器”。本节咱们简单介绍一下学习Kotlin的工具平台。
若是你想快速体验一下Kotlin,只须要浏览器打开云端IDE https://try.kotlinlang.org/
在这里你能够快速感觉到Kotlin语言到底长什么样子。可是,这里不支持代码智能提示以及自动补全等功能。
有时候咱们并不须要打开IDE来作一些事情。打开 IDE 是件很麻烦的事情,在某些场景下,咱们比较喜欢命令行。
使用命令行环境,咱们能够方便地使用Kotlin REPL(Read-Eval-Print-Loop,交互式编程环境)。REPL能够实时编写Kotlin代码,并查看运行结果。一般REPL交互方式能够用于调试、测试以及试验某种想法。
若是你想本地快速测试一个简短的Kotlin代码,可使用命令行REPL。Kotlin是运行在JVM环境下的语言。首先咱们要有JDK环境(Java环境配置此处省略)。
目前,Kotlin最新正式发布的版本是1.1.50。首先,去下载Kotlin运行环境安装包: https://github.com/JetBrains/...
解压完kotlin-compiler-1.1.50.zip,放到相应的目录下。而后配置系统环境变量:
export KOTLIN_HOME=/Users/jack/soft/kotlinc export PATH=$PATH:$KOTLIN_HOME/bin
执行source ~/.bashrc
, 命令行输入kotlinc
, 便可进入 Kotlin REPL界面
$ kotlinc Welcome to Kotlin version 1.1.50 (JRE 1.8.0_40-b27) Type :help for help, :quit for quit >>> println("Hello,World!") Hello,World! >>> import java.util.Date >>> Date() Wed Jun 07 14:19:33 CST 2017
咱们若是想拥有学习Kotlin的相对较好的体验,就不建议使用eclipse了。毕竟Kotlin是JetBrains家族的亲儿子,跟Intelli IDEA是血浓于水啊。
咱们使用IDEA新建gradle项目,选择Java,Kotlin(Java)框架支持,以下图:
新建完项目,咱们写一个HelloWorld.kt类
package com.easy.kotlin import java.util.Date import java.text.SimpleDateFormat fun main(args: Array<String>) { println("Hello, world!") println(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())) }
直接运行HelloWorld.kt,输出结果以下
Hello, world! 2017-05-29 01:15:30
如今的编程语言已经足够多了,为何咱们还须要更多的语言?Java已经如此流行普及足够强大了,为何咱们还须要Kotlin、Scala这样的语言呢?
其实,若是咱们仔细想一想,这个问题自己的逻辑就不成立。你想一想,咱们能这样说吗——煎鸡排已经足够好吃了,为何咱们还要去吃煎牛排呢?
从最先的机器语言(01机器码,汇编语言)到高级语言(Lisp,Basic,Pascal,C,C++,Java,Haskell等),再到现代编程语言(Go,Swift,Scala,Kotlin等),编程语言百花齐放、百家争鸣,其演化史可谓是蓬勃繁荣。
最先的编程语言就是01机器码(Machine Code)。那个时候的程序员要会用0和1表示一切!
后来人们聪明地想到,是否是能够把一些经常使用的指令操做单独抽象出来,用特定的关键字来映射01机器码序列?这就是汇编语言,这能够算做是编程语言过程当中的第一次抽象封装。
后来汇编用久了,人们也逐渐发现了使用汇编过程当中的问题:可移植性差。汇编代码中是大量的字节指令码,并且还必须一步一步地告诉计算机每一步要怎么作,一个步骤出错,执行结果就是程序员们意想不到的!调试程序也很困难。使用汇编语言编程,极易在子程序调用过程当中致使寄存器内容错误,而在高级语言中,全部参数都必须严格匹配。
高级语言就是为了解决汇编语言的这些问题进行的更高一层的抽象与封装。这层封装就是编译器。一般来讲,设计一门语言相对容易,而实现这门语言的编译器则是比较复杂的。编译器制定了一系列的协议规范、语法规则等,只要程序员们按照这个协议规范来编程,编译器就能够将高级语言的源代码翻译成对应CPU指令集上的汇编语言代码。高级语言不要求程序员掌握计算机的硬件运行,只要写好上层代码。著名的高级语言有 BASIC、FORTRAN(公式翻译)、 COBOL(通用商业语言)、 C、 PASACL、ADA 语言等。
尽管 C 语言 (1972, Dennis MacAlistair Ritchie,启发语言有 B语言、汇编、ALGOL68等)已经足够普及且很是强大,后来仍是出现了针对 C 语言进行改进和功能扩展的新语言 C++ ( 1979,Bjarne Stroustrup ),C++ 集成了 C 语言的特性,而后加入了面向对象程序设计的特性支持。
而C/C++语言最大的一个问题就是“一切都会尖叫着中止”,由于它们使用了直接操纵内存的指针。一旦由于使用指针而出现了内存错误,系统核心就会崩溃。
有没有一种语言能够控制这样的风险呢?
后来的Java(1995,James Gosling)继承了 C/C++ 语言的优势,摒弃了C++里的指针操做、手动管理内存、多继承等诸多复杂而并不实用功能特性,引入了划时代的 JVM(Java Virtual Machine)。引用James Gosling的话就是
“大部分人大谈特谈JAVA语言,这对于我来讲也许听起来很奇怪,可是我没法不去在乎。JVM才是Java生态系统的核心啊。
我真正关心的是Java虚拟机的概念,由于是它把全部的东西都联系在了一块儿;是它造就了Java语言;是它使得事物能在全部的异构平台上获得运行;也仍是它使得全部类型的语言可以共存。”
首先,JVM实现了Java的可移植性。
另外,JVM里面实现了一个垃圾收集器(GC,Garbage Collector)来管理内存,GC 对保证系统的可靠性和安全性很是实用有益。
同时,JVM还奠基了一个庞大的语言生态的基础。
Java是互联网时代当之无愧的最流行的开发语言。通过20多年的积累和沉淀,Java生态拥有了不少优秀的开源社区,如Apache和Spring。有了这些框架,咱们能够更加专一业务的实现。
Java语言也有很差的一面。咱们简单列举以下。
1.检查异常(Checked Exceptions)。检查异常会在编译时强制执行try catch处理,同时还须要进行某种排序处理。 检查异常是一个失败的实践,几乎全部的主要API提供者都反对可检查异常。Kotlin中摒弃了检查异常。
2.基本类型和数组。Java的这个设计保留了字节码的底层细节,违反了“凡事皆为对象”原则。泛型没法包容基本类型就是一个经典的例子。这也使得Java的类型系统显得不是那么地简单统一。比较好的方案是,源代码不用直接使用基本类型或者数组,编译器(或者JVM)来决定是否能够帮你对其进行优化。Kotlin正是这么作的。
3.静态变量(Static)。静态方法常常会致使须要显式的定义接口,从而使得API更加复杂。一个更好的办法就是采用单例对象,单例对象在大多数状况下表现都跟静态对象差很少,只不过也能够像一个对象同样被传递而已。Kotlin中提供了 object 单例对象。
4.泛型。Java泛型自己就很复杂,当使用? exends和? super等变种句型时就变得尤为复杂。很是容易搞错。这个问题在《Effective Java》一书中提出了PECS(Producer extends Consumer super)的建议,Kotlin直接使用了这个方案。
5.空指针异常(NPE)。Java中咱们不得不写一堆防护代码来避免使人头疼的NPE。Kotlin中引入了可空类型与安全调用符、Elvis操做符等特性实现空安全。咱们将在第3章中介绍。
6.一堆getter/setter单调冗长的样板代码。例以下面的Person Bean类
class PersonJava { Integer id; String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public PersonJava(Integer id, String name) { this.id = id; this.name = name; } }
在Kotlin中是这样子的:
data class PersonKotlin(val id: Int, val name: String)
7.不容易传递函数。Java中没有提供一等函数类型,函数式编程(FP)只能经过使用接口类型以及多态特性“曲线”来实现。Java会将每个算法(方法)都放入类中,这样的限制会出现这样的荒唐事:咱们只是想要实现一个函数算法,而这个时候咱们必须还得整出一个类出来放置这样的方法;一样,若是在其它地方要调用这个方法,咱们也必须经过建立该类来实现调用。在Kotlin中直截了当地提供了一等函数类型(First-Class Function Type)。跟普通类型同样,函数类型能够做为值来传递,也能够做为返回值。
还有其它的经验教训,上面所述只是其中的一部分。
不能否认的是, C、 C++ 和 Java 都是很是优秀的编程语言。可是事物老是不断发展变化的。就像 C++ 是对 C 的继承与发展,Java 是对 C++ 的继承与改造,而Kotlin也是对Java 的继承与变革。
这里是一张来自Java官网文档(http://docs.oracle.com/javase...)里面的一张 Java 技术模块架构图
为了在JVM上正确运行咱们的程序,咱们只须要可以按照规范生成正确的 class 文件,而后加载到JVM中执行文件中指定的操做字节指令码(byte code)便可。
在过去20多年的发展历程中(1991-2017,若是算上最初的称之为oak语言的Java前生的话),Java语言、JVM、API库和框架、应用工具和Web服务器的速度、稳定性和功能方面却一直在提高,如今已被公认为是开发高端服务器。
JVM最初是为了支持java编程语言。然而,随着时间的流逝,愈来愈多的语言被改编或设计运行在JVM上。除了java语言,比较知名的JVM上的编程语言还有:Groovy、Scala、Clojure等。
JVM上主流编程语言历史时间轴概览:
计算机中的全部问题 , 均可以经过向上抽象封装一层来解决。
Java虚拟机对各个平台而言,实质上是各个平台上的一个可执行程序。例如在windows平台下,java虚拟机对于windows而言,就是一个java.exe进程而已。
一般状况下,在JVM平台上语言从源代码编译到JVM上执行的总体过程以下图所示
其中,运行在JVM上的字节码文件是不依赖于硬件和操做系统的二进制格式的文件。依赖硬件和操做系统的部分,由JVM分别在这些平台上来实现。例如JDK 8
咱们常常说的Java语言是平台无关的,跨平台的。其实这是针对从Java/Scala/Kotlin/Groovy等的源代码到JVM字节码这一层是平台无关的。
可是,真正到了把JVM字节码经过解释器映射到不一样平台(操做系统,CPU硬件架构)上,JVM就必须针对各个平台实现一套解释器。只是这一层经过抽象封装,对 Java/Scala/Kotlin/Groovy 程序员而言已经彻底透明,无需再作相关的工做而已。
下一代广泛可接受语言(next mass-appeal language)中,人的因素应该起到重要做用。在功能方面,应该具有诸如如下特性:
语言设计其实堪比艺术品设计,每一个人的口味跟审美都有各自的风格与特征,因此实现出一门好的编程语言确实不容易。
人的生命只有一次。生命过短暂,因此不要去作一些重复无聊的事情。能交给计算机作的,就尽可能交给计算机去作。此乃人类进行计算机编程的滥觞之地。
将来人工智能将取代大部分的重复手工劳动。将大大解放人类的劳动力,从而使得人类可以花更多的时间和精力,去创造去创新。而人工智能的本质,就是对人类智能的抽象建模。咱们人类写的操做系统、浏览器、办公软件、画图设计工具、3D建模软件、电商系统、金融平台、社交APP,不就是另外一种层次上的人工智能吗?这些东西,背后都是01的映射。固然,01背后是物理层次的,量子微观的世界了,更加奥妙无穷。
纵览整个计算机的发展史,最重要的思想非“抽象”莫属。
一层层的抽象封装了实现的细节,计算机开疆扩土,南征北战,发展到了今天蔚为壮观的互联网,云计算,大数据,机器智能的时代。
同时,也使得程序员写代码,从最初的拿着符号表在纸袋上打孔,到使用近似天然语言的高级编程语言来编程(固然背后少不了编译器、解释器,还有的是先经过虚拟机中间字节码这一层,再经过解释器映射到机器码,最后在硬件上做高低电平的超高频率的舞蹈),以及当今各类库API、框架、集成开发工具集,智能化的编码提示,代码生成等等技术,使得咱们如今程序员,能更多的去关注问题自己以及逻辑的实现。
从只有少数技术人会用的命令行的Unix、DOS操做系统,到人性化的GUI图形界面操做系统,再到移动互联网时代的智能设备,计算机与互联网愈来愈融入到人类生活的方方面面。
正如解决数学问题一般咱们会谈“思想”,诸如反证法、化繁为简等,解决计算机问题也有不少很是出色的思想。思想之因此称为思想,是由于“思想”有拓展性与引导性,能够解决一系列问题。
解决问题的复杂程度直接取决于抽象的种类及质量。过将结构、性质不一样的底层实现进行封装,向上提供统一的API接口,让使用者以为就是在使用一个统一的资源,或者让使用者以为本身在使用一个原本底层不直接提供、“虚拟”出来的资源。