Kotlin

JGSK - Kotlin - 07.内联函数

内联函数

概念

普通函数在执行时程序会跳转到函数定义处执行完毕后再返回调用处。而内联函数指的是函数定义被整个复制到了调用处,所以与普通函数相比,内联函数无需进行程序的跳转,有助于提高程序的运行速度。但是大量的内联函数会增大应用的体积,从而减慢应用的加载速度。

JGSK - Kotlin - 06.DSL

DSL

DSL 即 domain-specific languages,领域特定语言。和一般的编程语言不同,领域特定语言只能用于特定的领域中并且表现形式有限。领域特定语言最大的功能就是可以让语言本身更容易阅读,方便开发者和领域专家进行交流。

JGSK - 35.集合的函数式编程

Java

从 Java 1.8 开始 Java 也支持了集合的函数式编程。

Stream

Stream 是 Java 1.8 引入的类,主要用于进行 并行集合的流式操作。

集合可以使用调用 stream() 方法或者使用 Stream 类的静态方法来转换为 Stream 对象。

JGSK - Kotlin - 04.this

this

  • 在 Java 中 this 通常用于指代当前对象,而在 Kotlin 中由于拥有闭包,扩展等特性,this 的指代变得更加复杂。
  • 就像 Java 可以使用 类名.this 类指代外部类的对象,Kotlin 中可以使用 `this@类名 来达到同样效果。

JGSK - Kotlin - 02.Extension

Extension

Extension 是 Kotlin 中一个非常强大的功能,主要用于对已经定义好的类的行为或者属性进行扩展,这一特性非常类似 Javascript 中的 Prototype。

JGSK - Kotlin - 01.多重声明

多重声明

多重声明类似 Scala 中的 unapply,主要用于对对象进行拆箱。

实现多重声明只要在任意类内部定义了 componentN() 方法(N 为任意自然数)即可并加上 operator 关键字即可。

JGSK - 34.Lazy

共通篇

Lazy变量也就是常说的惰性加载,即变量在初始化时没有进行计算操作,而是延迟到了该变量第一次被使用的时候。在函数式编程中,惰性加载被广泛使用,尤其是对于一些长度未知的列表,如果使用普通方式,恐怕加载时系统就会被拖慢速度甚至于内存溢出。

JGSK - 33.Reflect 与 Annotation

Java

注解

注解主要用于标示元数据。Java 中声明一个注解使用符号 @interface

创建一个注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Bean {
    String name();
}

以上创建了一个名为 Bean 的注解。该注解上使用了标示此自定义注解的两个 JVM 的内置注解:RetentionTarget

JGSK - 32.Shell

Java

执行 Shell 命令

Java 中执行 Shell 命令主要依靠 Runtime 和 Process 两个类。

JGSK - 31.Test

共通篇

测试过程分类

测试过程通常有 N 种分类,一般常说的有那么几种: UT,IT(CT),ST,MT。

UT 单元测试属于白盒测试,是测试中的最小单元,一般用于测试单独的方法,检测方法的正确性。

JGSK - 30.Thread 与 Future

Java

Thread

线程主要用于执行并发任务,提高 CPU 的运行效率。在各种参考中都有线程相关的各种概念,在这里就补多废话了。在Java 中线程相关的概念主要有两个: Thread 和 Runnable。

JGSK - 29. 与 Java 交互

共通篇

Groovy,Scala 和 Kotlin 都是 JVM 上的语言,在设计之初就考虑到了与 Java 的兼容性,所以这三门语言几乎都能无缝调用 Java 代码,因此也能很简单地实用现在众多成熟的 Java 类库。而 Java 调用这三门语言也不是太麻烦,所以可以根据实用场景在这四门语言中进行便捷地切换。

JGSK - 28.IO

共通篇

Java 中的 IO 操作主要是对各种流进行操作。Java 中流可以分为字节流(InputStream),字符流(FileReader),转换流(InputStreamReader)等。这种设计方式一直都被认为是非常优秀的。 由于流的种类繁多,使用起来有固定的套路,并不复杂,所以本章只是简单介绍一下。

JGSK - 27.泛型 - Groovy篇

Groovy 中使用的就是 Java 的泛型,所以参考 Java 就行了。但是要注意的是由于 Groovy 的动态特性,所以有些Java 会报的编译错误在 Groovy 中只有运行时才会发现。

JGSK - 27.泛型 - Java篇

泛型

基本概念

泛型是 Java 1.5才引进的特性。泛型使类型参数化变得可能。在声明类或接口时,可以使用自定义的占位符来表示类型,在运行时由传入的具体类型进行替换。泛型的引入让集合变得更加好用,使很多错误在编译时就能被发现,也省去了一些强制转换的麻烦。

JGSK - 26.Xml 与 JSON 的处理

共通篇

JSON 是一种键值对形式的轻量级的数据交换格式,除了大量用于 Restful 请求外,其二进制形式的 BSON 也被用于作为 NO SQL 的数据存储格式。相比较 XML 而言,JSON 更为简单,灵活。

XML 也可以用于数据交换,最为有名的就是 SOAP 协议。相比较 JSON 而言由于需要有开始和结束标记所以 XML 略显啰嗦。不过相比较 JSON 的无模式形式,XML 可以通过指定 DTD 而为其中定义的数据指定一定的格式,所以可以作为配置文件,在使用 IDE 进行编辑时也能拥有代码提示功能。

JGSK - 25.正则表达式

共通篇

正则表达式功能非常强大,但是写好一个满足各种情况的合格的正则表达式却不是件简单的事。

本章节不会介绍任何正则表达式的语法,而是介绍四种语言中正则表达式最基本的三种用法:匹配,查找和替换的实现方式。

JGSK - 24.枚举

Java 篇

枚举是种特殊的类,主要用于构建一组特定的值。在 Java 中通常用于限定某个属性的值只能在一定范围内,在某些场合可以被静态常量代替,但是枚举可以有自己的属性也可以有自己的方法,而静态常量无法做到,且静态常量只能限定类型,不能限定值本身。当然在效率上,枚举并不如静态常量。

JGSK - 23.Trait

共通篇

Trait 中文名为特质。特质是字段和行为的集合,可以拥有抽象成员也可以拥有普通成员。特质可以看做是一种特殊形式的接口,但是特质主要用于实现多重继承。

多重继承虽然便利,但是会带来 Diamond Problem,即 B 和 C 都实现了 A 的某个方法,而 D 继承了 B 和 C 但是没有重写该方法,此时调用 D 持有的该方法到底来自于 B 还是 C。因此过分使用特质会让程序本身难以理解。

JGSK - 22.包与访问权限

Java 篇

创建包

  • Java 使用关键字 package 来声明一个包。
  • 包名中使用 . 作为路径分隔符,且包路径必须与源文件路径相同。
  • 包只能声明在源文件开头。
package a.b;
class B {}

JGSK - 21.异常

Java 篇

Java 中异常是种特殊对象,可以分为检查异常和非检查异常,所有 RuntimeException 都属于非检查异常。

非检查异常表示程序正常运行时不应该会发生的异常,所以无需对非检查异常进行额外的检查。

JGSK - 18.类相关:Data类 - Kotlin 篇

Data Class

特点

  • Data 类是使用关键字 data 声明的类
  • Data 类默认基于构造方法实现了 toString(), componentN(), copy(), equals()hashCode() 方法,不在构造方法中定义的属性不会产生在 toString() 结果中。
  • Data 类可以直接使用 == 进行比较,同样不在构造方法中定义的属性不会用在比较上
  • Data 类只表示数据,不能拥有行为,所以通常来说我们没有必要为 Data 类构建类体

JGSK - 20.switch 与模式匹配

Java 篇

Switch

  • Java 中 switch 语句功能类似 if,但是 switch 主要用在多条件分支上。
  • switch 语句由 case 分支和 default 组成,case 分支用于检查条件,且参数必须为常量,default 用于执行当任何 case 分支都不匹配时执行的语句。
  • switch 语句 在 Java 1.7 以前只支持基本类型,Java 1.7 开始支持 String
  • 执行时 switch 语句会从上而下检查与 case 条件是否一致,一旦发现相等的分支,switch 语句就会执行该条 case 分支下的语句,并且之后会忽略下面的所有 case 分支,直到遇到 break 才会停止执行。

JGSK - 19.继承,抽象类与接口

Java 篇

抽象类

  • 抽象类是使用关键字 abstract 声明的类。抽象类与普通类的最大区别是抽象类不能被实例化。
  • 抽象类可以拥有没有方法体的抽象方法也可以拥有普通方法,抽象方法使用 abstract 声明。
  • 普通类可以使用关键字 extends 继承普通类,继承时必须重写所有抽象方法。
  • 普通类可以继承抽象类,抽象类可以继承抽象类。

JGSK - 18.类相关:样本类 - Scala 篇

样本类 Case Class

特点

  • 样本类是使用关键字 case class 声明的类。它可以隐式调用构造方法进行初始化,样本类没有副构造方法。
  • 样本类默认基于构造方法实现了 toString(), equals()hashCode() 方法,不在构造方法中定义的属性不会产生在 toString() 的结果中。
  • 样本类可以直接使用 == 进行比较,同样不在构造方法中定义的属性不会用在比较上
  • 样本类被大量使用在模式匹配中

JGSK - 18.类相关:Object - Scala & Kotlin篇

Scala 篇

Object

单例对象

在 Java 中实现单例对象通常需要自己实现一个类并创建 getInstance() 的方法然后在该方法里使用两次同步块或者使用更为优雅的基于 enum 的方式。而 Scala 中则更加简单,只要使用 object 声明就能创建一个单例对象。实际上之前我们创建的拥有 main() 方法的都是单例对象。

JGSK - 17.内部类

共同篇

所谓的内部类即定义在类内部的类,而包含这个内部类的类则被称作外部类。通常来说内部类可以访问外部类的私有成员,作为外部类的内部扩展而存在。

Java 篇

静态内部类

静态内部类即以 static 关键字声明的内部类。静态内部类不属于外部类的成员,使用上与普通的外部类没有什么区别。

JGSK - 15.类 - Kotlin 篇

定义一个类

Kotlin 同 Scala 一样使用关键字 class 来定义类,同时类的属性必须明确指明初始值。

class Person {
    //  属性
    var age = 0
    //  行为
    fun say(message: String) {
      println(message)
    }
}

JGSK - 15.类 - Scala 篇

定义一个类

Scala 中也使用关键字 class 来定义类,但是类的属性必须明确指明初始值,而不是像 Java 和 Groovy 一样有默认值。

class Person {
    //  属性
    var age = 0
    //  行为
    def say(message: String) {
      println(message)
    }
}

JGSK - 15.类 - Groovy 篇

定义一个类

Groovy 中也使用关键字 class 来定义类

class Person {
    //  属性
    def age
    //  行为
    def say(message) {
        println(message)
    }
}

JGSK - 15.类 - Java 篇

总述

类在面向对象编程中是一个最基本的概念。类是对象的模板,用于产生具有相同结构的对象。一个类通常由属性和行为构成。

定义一个类

Java 中使用关键字 class 来定义类

JGSK - 14.映射与元祖

共通篇

映射是由键值对组成的一组数据的集合。映射通常基于哈希表,最常见的实现就是 HashMap。

元组类似列表,也是表示一组数据,但是元组中的数据通常都是不同类型或者数据间表示不同含义。且元组通常只用于传递数据,所以不能进行修改。

JGSK - 13.数组,集合与范围

共通篇

数组在程序中用于表示一组特定的值,通常来说数组的大小是预先指定的,数组的元素类型也是统一的,所以访问数组时可以通过偏移量快速访问任意一个元素。

集合类似数组,很多时候集合也是通过数组实现的,但是集合的长度是可变的,存储的数据类型也可以不一样(尽管一般都是存储同类型的数据)。集合通常有两种:List 和 Set,一般来说,前者有序且元素可以重复,后者无序但元素不能重复。

JGSK - 12.循环

Java 篇

For

for 语句可以说是最常用的循环语句了。Java 支持普通的 for 语句以及增强型的 for-each 语句。

for 语句

for (int i = 0; i < 3; i++) {
    System.out.println("Repeat For " + i);
}

JGSK - 11.条件表达式

Java 篇

if

if 语句用于表达这样一种概念,在某种条件下执行一种操作,在另一种条件下执行另一种操作。 Java 中的 if 语句如果操作只有一行语句的话可以省略花括号,尽管很多书籍不建议使用这种方式。

JGSK - 10.脚本

共通篇

脚本,是使用一种特定的描述性语言,依据一定的格式编写的可执行文件。通常可以用于执行一些简单的代码。

JGSK - 09.Null

Java 篇

null

Java 使用关键字 null 表示空值,即没有任何引用。使用 == 来判断一个值是否是空值。

Integer x = null;
System.out.println(x == null);

JGSK - 07.String

Java 篇

声明字面量

String s = "Hello World";

遍历字符

for (char c : s.toCharArray()) {
    System.out.println(c);
}

JGSK - 05.数据类型

Java 篇

Java 的数据类型主要分为基本数据类型和引用数据类型。

基本类型

Java 的基本类型有 int, long, float, double, char, boolean,即以小写字母开头的数据类型。

JGSK - 02.REPL 环境

REPL 为 “Read Evaluate Print Loop” 的简写,即 “读取-求值-打印-循环”,是一些动态语言的标准特性,主要用于进行探索式编程。也就是说当你不清楚某项计算的结果或者忘记了某个方法的作用时,可以输入代码片段并立即获得结果。

JGSK - 03.创建 Maven 工程

概述

在进行各种测试之前,我们先为之后的所有例子建立一个完整的工程项目。我使用的开发工具为 IDEA 14 CE,构建工具选择最为通用的 Maven。

JGSK - 01.安装与运行

Begin

Overview

本系列主要是对 Java,Groovy,Scala 和 Kotlin 这四种 JVM 上的语言做一些粗浅的对比。对于那些语言本身提供但是却不提倡使用的功能本系列大都不会提。本系列主要使用的开发环境为 Windows 和 Mac,IDE 为 IDEA 和 Eclipse,构建工具为 Maven 和 Gradle。