Kotlin or Java?(简单聊聊Kotilin)

随便看看 专栏收录该内容
1 篇文章 0 订阅

Kotlin or Java?

结论放前面。根据个人的一些了解和受限于经验和眼界,个人认为kotlin是一门非常有潜力的语言,语法糖真的甜,也可实现和Java的混编。Kotlin Native的实现,可以让Kotlin不单单可以通过运行在JVM上实现跨平台,更可以直接生成对应平台上的二进制可执行文件实现跨平台。

在移动端开发领域,Kotlin Native实现了同一份代码既可以在Android平台也可以在IOS平台上运行。而且Kotlin在被Google官宣作为Android的一级开发语言后,在移动端Kotlin的生态绝对得到了保障

但是是否需要完全投入Kotlin还是要打一个问号的,毕竟没有紧迫的需求,系统的稳定才是第一位的。在Web开发领域,Kotlin相对于Java并没有特别高的优势。但是由于Java在老流氓Oracle手中,Kotlin被谷歌大力推行,多学一门学习成本不高的新技术,还是非常值得的。

Kotlin和Java的关系

Kotlin是JetBrains 公司开发的一款运行在JVM上的静态编程语言,其设计目标是创建一种兼容Java的语言。

因为其都是运行在JVM上,所以可以说是兄弟关系,类似的语言还有大名鼎鼎的Scala,Groovy,以及Jython,JRuby等。这一类语言都通过JVM实现了跨平台的特性。

但是Kotlin有所不同的是,它实现了自己的一个编译器Kotlin Native,直接将Kotlin代码编译成可执行的目标平台的二进制文件,而不是字节码,以此实现跨平台的特性。从这点来说,它和Java的关系又远了一些。更远一点来说,Kotlin可以不依赖JVM而实现编译和执行,也就不会存在大量公司到现在还使用Java8进行开发的尴尬局面了。

JVM和Kotlin Native

Kotlin优于Java,网上更多的聊了各种语法方面的问题(在我看来),诚然Kotlin作为一门比较新的语言,并且目标是兼容Java的语言,其针对Java的一些痛点有针对性的做出了改进,让语言变得更简洁,也更“动态”。

但是在介绍语法上的区别之前,我更想介绍一下Java和Kotlin如何实现跨平台的。

为什么需要跨平台?

因为你觉得不需要跨平台的东西,都是有大佬定义了一堆规范的,比如没事就定义各种协议的IEEE协会。大家都基于一个协议就能方便开发,促进行业发展。但是社会要发展,小弟也想做大哥。基于各种场景和现实需求,会有新的一套规范出来。可能这套规范是老大哥提出的,也可能是小弟提出的。

对于程序开发来讲,我们的平台主要有Windows,Linux,移动端的Android,IOS,以及一些其他IOT设备的一些平台,每个平台底层执行架构的不同决定我们需要不同的机器语言来让告诉机器执行什么命令,无疑是低效的。所以跨平台的语言是大势所趋。

JVM

Java实现跨平台是通过JVM来实现的。JVM(Java Virtual Machine)是一种规范,并不是特定的某个编译器。它规定了这个编译器要实现哪些功能,具体的实现由各个厂家实现。目前比较常用的是Oracle JDK,Oracle OpenJDK, Red Hat build of OpenJDK等,以及我们大厂开发的腾讯Kona JDK,阿里巴巴Dragonwell JDK,华为毕昇JDK等。在后文我们用JVM指代字节码的运行时环境。

基于JVM的语言由编译器先编译成字节码文件,字节码文件再运行在JVM中,由JVM负责与OS的交互,因此程序员几乎可以不考虑平台,而只考虑业务逻辑进行编程开发。

JAVA被称为是半静态,半动态的语言。很多博客的解释说是因为Java先通过编译生成字节码文件,然后JVM对字节码进行翻译实行,所以称为半静态,半动态语言。其实我觉得这样说法是有误的。事实上是因为字节码文件在执行初期是使用翻译执行也就是动态语言(例如Python)的执行方式,所以其编译速度很快,但是执行的效率因为没有经过指令优化,因此是比较慢的。但是随着程序的执行,JVM中的JIT(Just-in-time compilation)模块会对其中执行热度高的代码进行编译,生成目标平台的二进制执行文件,这里就用上了指令优化,可以让代码更快的运行,理论上字节码程序运行时间足够长,所有的代码都会被编译,获得更快的运行速度和更少的运行时内存。

因此Kotilin和Java如果都是基于JVM运行,那么JVM带来的优势他们都是可以享受到的。也不会说基于JVM运行的代码比类似C++这类直接编译生成可执行文件的编程语言运行慢的问题。

这里最大的问题是,通用的JDK大家都使用Oracle JDK8而不是其最高版本,因此也享受不到高版本的JDK新特性,可能这也就是大厂自研JDK的一部分理由

Kotlin Native

先看看官方的解释

为什么选择Kotlin/Native

Why Kotlin/Native?

Kotlin/Native is primarily designed to allow compilation for platforms where virtual machines are not desirable or possible, for example, embedded devices or iOS. It solves the situations when a developer needs to produce a self-contained program that does not require an additional runtime or virtual machine.

Kotlin/Native主要设计为允许编译不需要或不可能使用虚拟机的平台,例如**嵌入式设备或iOS。**它解决了开发人员需要生成不需要额外运行时或虚拟机的自包含程序的情况。

传闻IOS不能使用Java开发的一个原因就是因为基于JVM运行,不够安全(在运行时可以通过classLoader加载新的类,理论上可以安插一些恶意代码)和IOS的思想不符合。

再看看目前Kotlin Native支持的平台

Kotlin/Native supports the following platforms:

  • iOS (arm32, arm64, simulator x86_64)
  • macOS (x86_64)
  • watchOS (arm32, arm64, x86)
  • tvOS (arm64, x86_64)
  • Android (arm32, arm64, x86, x86_64)
  • Windows (mingw x86_64, x86)
  • Linux (x86_64, arm32, arm64, MIPS, MIPS little endian)
  • WebAssembly (wasm32)

可以看到主流的一些平台都是有支持的,包括可以运行JVM的Windows和Linux。其实Kotlin Native的重点还是在于可以打通Android和IOS平台。官方文档表达的意思也是如此,例如下面的描述:

It is easy to include a compiled Kotlin code into existing projects written in C, C++, Swift, Objective-C, and other languages. It is also easy to use existing native code, static or dynamic C libraries, Swift/Objective-C frameworks, graphical engines, and anything else directly from Kotlin/Native.

主要还是集中在Android开发和IOS开发。但是这个用词非常的熟悉。因为之前多次看到这样一句话“Kotlin可以方便的利用现有的Java库”

具体的Kotlin Native性能方面的资料较少,这里也可以和JVM的各种资料做个对比,虽然Kotlin也是开源的,但是社会上的热度明显还是低于Java。

Native相对于JVM来说,因为直接编译成二进制文件,做了指令优化,所以编译的时间会更久,执行的速度会更快。但是JVM长时间运行后的效率未测**(TODO)**但是根据社区反馈也有一些优化上的问题(例如SIMD),但是背靠JetBrains以及谷歌,肯定也不赖。

Kotlin基础语法及语法糖

一门语言基础语法决定了入门的难易程度。比如津津乐道的大学为什么首选编程语言是C而不是Python。从我的角度来说Python作为一门动态语言,语言的习惯和英语更像,而且没有很多的条条框框。跟重要的是C需要考虑内存,指针而Python什么都不需要,也不太需要了解数据类型。大量的工作交给编译器自动进行了。

Java作为后来的高级编程语言,屏蔽了指针这个比较抽象的概念,保留了变量需要严格数据类型定义的特性,简单容易上手,又方便管理。但是相对于灵活的动态语言来说,还是条条框框太多了。因此Kotlin作为目标是兼容Java的语言,针对Java的一些冗长表达,结合其他语言的优秀特性,建立了一套自己的语言规范。

什么是语法糖

其实上述讲的语言的优秀特性都属于广义的语法糖的范围。语法糖其实是指一些某种计算机语言中的某种语法(某种表达式或者函数),这种语法对语言的功能没有影响,或者说没有突破性的改变,但是他包装了程序员的一些常用但是实现复杂的一些操作,实现用简短的表达式实现某种功能,增加程序的可读性,提高程序员编程效率。

两个例子

C++中对二位数组的取值

// 取二维数组中第i行第j列
*(*(a+i)+j);
//语法糖
a[i][j]

Python中对数组的切片操作

## 包含六个数的数组
a = [1,2,3,4,5,6]
## 复制一个新的数组
b = a[:]
## 取前三个
c = a[:3]
## 取第3-6个数
d = a[2:5]
## 读取倒数第二个数
a[-2]

基础语法和语法糖很难分开介绍,而且专门的基础语法介绍又比较繁琐冗长。因此接下来的介绍仅介绍我觉得必须了解的部分语法以及印象深刻的语法糖。详细的基础语法可以看菜鸟教程。作为可以兼容Java的语言,其语法特点和Java其实是很相似的,我也会把Java和Kotlin的语法进行一个对比(以JDK8为标准)

定义变量、常量及函数

作为写程序用得最多的语法,如果能少敲几下键盘,但是又不影响程序的理解,何乐而不为呢?

定义一个函数

关键字fun:定义一个函数。参数格式为:参数名称 : 类型

kotlin中很神奇的一个地方就是将参数的类型放到了参数名称之后。虽然没有人要求参数类型一定要在参数名称的前面,kotlin官方的解释是这样更为直观,笔者不置评论。

kotlin中函数的定义借鉴了很多动态语言

// 标准格式
fun sum(a: Int, b: Int): Int {   // Int 参数,返回值 Int
    return a + b
}

// 返回类型自动推断
fun sum(a: Int, b: Int) = a + b

public fun sum(a: Int, b: Int): Int = a + b   // public 方法则必须明确写出返回类型

// 无返回值的函数
fun printSum(a: Int, b: Int): Unit { 
    print(a + b)
}


// 如果是返回 Unit类型,则可以省略(对于public方法也是这样):
public fun printSum(a: Int, b: Int) { 
    print(a + b)
}

可变长参数函数

关键字vararg

fun vars(vararg v:Int){
    for(vt in v){
        print(vt)
    }
}

// 测试
fun main(args: Array<String>) {
    vars(1,2,3,4,5)  // 输出12345
}

匿名函数lambda表达式

// 测试
fun main(args: Array<String>) {
    val sumLambda: (Int, Int) -> Int = {x,y -> x+y}
    println(sumLambda(1,2))  // 输出 3
}

函数重载

更为只能的参数匹配方式,只写一个包含所有所需参数的函数,传参指定默认值。就可以任意的传入参数,而不用重复的写重载函数

img

这里可以看到IDEA的支持真的不错,毕竟是自家的语言。这种风格和Python之类的动态语言真的太像了,非常方便。

定义变量和常量

var:定义一个可变变量

val:定义一个长脸(只能赋值一次的变量,类似Java中final修饰的变量)

val a: Int = 1
val b = 1       // 系统自动推断变量类型为Int
val c: Int      // 如果不在声明时初始化则必须提供变量类型
c = 1           // 明确赋值


var x = 5        // 系统自动推断变量类型为Int
x += 1           // 变量可修改

lateinit:让编译器在检查时不要因为属性变量未被初始化而报错。lateinit可以在任何位置初始化并且可以初始化多次。

by lazy{}:by lazy只能作用于val关键字标注的属性。当属性用到的时候才会初始化”lazy{}”里面的内容,而且再次调用属性的时候,只会得到结果,而不会再次执行lazy{}的运行过程。

顶层属性和顶层函数

在Java中一切皆对象,所以有时候我们仅仅只是想建立一个静态方法,或者储存一些静态的变量,我们需要建立一个类,并在类中写静态方法和静态变量。但是在实际情况中类似XXXUtils和XXXHelper等类是不需要建立对象的,那么这个类就显得有点多余。

因此在Kotlin中,实现了类似脚本的写法。顶层属性和顶层函数的位置和class是同级的

顶层属性和顶层函数的作用于是包,即同一个包中可以不用Import而直接调用。而跨包的调用则需要Import。

原理上,顶层文件会反编译成一个容器类。(类名一般默认就是顶层文件名+”Kt”后缀,注意容器类名可以自定义,通过@JvmName),顶层函数会反编译成一个static静态函数

最经典的顶层函数就是main()函数

package entity
var USER_TYPE:String = "human"

fun main(){
    var user=User()
}


class User {
    var name:String="name"
}

小结

Kotlin相对于Java来说,从语言风格上更加的贴近动态语言。并且引入了类型推断(JDK10也引入了var关键字用于类型推断)。顶层属性和顶层函数的引入,可以少写一些类的代码,但是可能会让层级略显混乱。并且这些方法不可以被继承。如果需要在类中实现静态方法,反而会比较复杂一些。lateinit关键字开始让我觉得似乎不太安全,但是由于Kotlin有完善的非空判断机制,也没没什么关系了。

非空判断

Kotlin的空安全设计是最为吸引人的部分,有效的解决Java中的空指针异常。只需要使用?或者!

?和!!

"?“加在变量名后,系统在任何情况不会报它的空指针异常,用于显式标记变量可以为空。”!!"加在变量名后,如果对象为null,那么系统一定会报异常,用于显式标记变量绝对不能为空。这两个符号能让开发者明确对变量空值的感知。任何一个变量,如果不加上?,相当于默认加上了!!。

roomList?.size 返回的是 null 或者是 roomList的大小。

而且很神奇的是,“?”并不会和“a?b:c”这样的语句产生混淆,如果a为空,那么返回C,不然就返回b。非常直接!

一个非常极端的例子

Java嵌套类属性的调用

class A{
    B b;
}
class B{
    C c;
}
class C{
    D d;
}
class D{
    public String name;
}

public class User {
    public static void main(String[] args) {
        A a = new A();
        if(a.b!=null && a.b.c !=null && a.b.c.d != null){
            System.out.println(a.b.c.d.name);
        }
    }
}

更优雅的Kotlin

class A{
    var b:B ?= null
}
class B{
    var c:C ?= null
}
class C{
    var d:D ?= null
}
class D{
    var name:String ?= null
}

fun main(){
    val a = A()
    println(a.b?.c?.d?.name?:"")
}

if(xxx != null)这种判断可以少写很多了。

升级版区间、循环控制和条件控制

更方便的便利区间

遍历从0到100,看以下代码

java

//java
for(int i=0;i<=100;1++){
	dofun()
}

python

## python
for i in range(101):
	dofun()

kotlin

// kotlin
    for (i in 1..100) { …… }  // 闭区间:包含 100

    for (i in 1 until 100) { …… } // 半开区间:不包含 100

    for (x in 2..10 step 2) { …… }

    for (x in 10 downTo 1) { …… }

    if (x in 1..10) { …… }
     for (index in items.indices) {

        println("item at $index is ${items[index]}")

    }

    for ((k, v) in map) {

        println("$k -> $v")

    }

    x !in a..b

标签处返回

Kotlin 有函数字面量、局部函数和对象表达式。因此 Kotlin 的函数可以被嵌套。 标签限制的 return 允许我们从外层函数返回。 最重要的一个用途就是从 lambda 表达式中返回。回想一下我们这么写的时候:

fun foo() {
    ints.forEach {
        if (it == 0) return
        print(it)
    }
}

这个 return 表达式从最直接包围它的函数即 foo 中返回。 (注意,这种非局部的返回只支持传给内联函数的 lambda 表达式。) 如果我们需要从 lambda 表达式中返回,我们必须给它加标签并用以限制 return。

fun foo() {
    ints.forEach lit@ {
        if (it == 0) return@lit
        print(it)
    }
}

现在,它只会从 lambda 表达式中返回。通常情况下使用隐式标签更方便。 该标签与接受该 lambda 的函数同名。

fun foo() {
    ints.forEach {
        if (it == 0) return@forEach
        print(it)
    }
}

或者,我们用一个匿名函数替代 lambda 表达式。 匿名函数内部的 return 语句将从该匿名函数自身返回

fun foo() {
    ints.forEach(fun(value: Int) {
        if (value == 0) return
        print(value)
    })
}

当要返一个回值的时候,解析器优先选用标签限制的 return,即

return@a 1 //意为"从标签 @a 返回 1",而不是"返回一个标签标注的表达式 (@a 1)"。

条件控制

if表达式赋值

前面提到三元操作符“?:”,kotlin通过把if表达式的结果复制给一个变量获得更清晰的语义

//可以这样
val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}
// 或者直接
val c = if (condition) a else b

when
多个条件判断我们常用switch,kotlin实现了更丰富的功能,使用when in else关键字。如果满足条件in,就执行,只有都不满足,才执行else。

分支并不会像switch一样继续往下,所以并不需要break的功能。多个

var validNumbers = {1,2,3};
when (3) {
	1 -> print("x==1")
    2 -> print("x==2")
    3,4 -> print("x==3orx==4") // 多个条件或
    in 1..10 -> print("x is in the range") //区间判断
    in validNumbers -> { // 也可以实行函数块
        print("x is valid")}
    !in 10..20 -> print("x is outside the range")
    is String -> x.startsWith("prefix") // 类型判断
    else -> print("none of the above")
}
/*输出结果
x==3orx==4
 */

import包重命名

在Java中,对于全限定类名不同,但是类名相同的类,我们使用时将会使用全限定类名,如下:

package com.day01.three;
public class User {
    private com.day01.one.User u;
    private com.day01.two.User u2;
}

而在Kotlin中,支持对包名进行重命名,方便引用,如下所示:

package three

import one.User as oneUser;
import two.User as twoUser;

class User {
    var u1 = oneUser()
    var u2 = twoUser()
}

类和对象

Kotlin针对不同用途的类,提供了不同的关键字来定义类,以实现不同的功能

open关键字

在java中允许创建任意的子类并重写方法任意的方法,除非显示的使用了final关键字进行标注。

而在kotlin的世界里面则不是这样,在kotlin中它所有的类默认都是final的,那么就意味着不能被继承,而且在类中所有的方法也是默认是final的,那么就是kotlin的方法默认也不能被重写。

如果想类可以被继承或者方法可以被重写,那么就需要在类或者方法前显式添加open关键字。并且重写的方法前还需要显示的添加override关键字

数据类

我们经常创建一些只保存数据的类。 在这些类中,一些标准函数往往是从数据机械推导而来的。在 Kotlin 中,这叫做 数据类 并标记为 data:

 data class User(val name: String, val age: Int)

编译器自动从主构造函数中声明的所有属性导出以下成员:

  • equals()/hashCode() 对
  • toString() 格式是 “User(name=John, age=42)”;
  • componentN() 函数 按声明顺序对应于所有属性;
  • copy() 函数(见下文)。

Lombok插件再见

为了确保生成的代码的一致性以及有意义的行为,数据类必须满足以下要求:

主构造函数需要至少有一个参数;

主构造函数的所有参数需要标记为 val 或 var;

数据类不能是抽象、开放、密封或者内部的;

此外,成员生成遵循关于成员继承的这些规则:

如果在数据类体中有显式实现 equals()、 hashCode() 或者 toString(),或者这些函数在父类中有final 实现,那么不会生成这些函数,而会使用现有函数;

复制

在很多情况下,我们需要复制一个对象改变它的一些属性,但其余部分保持不变。 在数据库更新操作中特别多。copy() 函数就是为此而生成。对于上文的 User 类,其实现会类似下面这样:

fun copy(name: String = this.name, age: Int = this.age) = User(name, age)

这让我们可以写:

val jack = User(name = "Jack", age = 1)

val olderJack = jack.copy(age = 2)

属性扩展和函数扩展

属性扩展

var StringBuilder.lastChar: Char get() = get(length -1)

    set(value: Char) { this.setCharAt(length -1, value)

                     }

fun main() {

    val sb = StringBuilder("kotlin") println(sb.lastChar) sb.lastChar = '!' println(sb.lastChar)

}

函数扩展

// 为String类新增一个属性值customLen
var String.customLen:Int
    get() = length
    set(value) {
        println("set")
    }

fun main(args: Array<String>){
    val name = "xencio"
    println(name.customLen) //6
    name.customLen = 10 // set
    println(name.customLen) //6
}

注意:

1、扩展函数并不允许你打破它的封装性,和在类内部定义的方法不同的是,扩展函数不能访问私有的或是受保护的成员。

2、扩展函数并不是真正地修改了原来的类,其底层其实是以静态导入的方式来实现的。扩展函数可以被声明在任何一个文件中,因此有个通用的实践是把一系列有关的函数放在一个新建的文件里

3、需要注意的是,扩展函数不会自动地在整个项目范围内生效,如果需要使用到扩展函数,需要进行导入

4、对于扩展函数,如果子类和父类有同名扩展函数,调用哪个扩展函数是由变量的静态类型来决定的。而非这个变量的运行时类型

5、如果子类和父类有同名的扩展对象,那么调用哪个扩展对象是由变量的静态类型来决定的。而非这个变量的运行时类型

6、如果一个类的成员函数和扩展函数有相同的签名,成员函数会被优先使用

Object类

将类的声明和定义该类的单例对象结合在一起(即通过object就实现了单例模式)。

object declaration的类最终被编译成:一个类拥有一个静态成员来持有对自己的引用,并且这个静态成员的名称为INSTANCE,当然这个INSTANCE是单例的,故这里可以这么去使用。

和普通类的声明一样,可以包含属性、方法、初始化代码块以及可以继承其他类或者实现某个接口,但是object它不能包含构造器。

它也可以定义在一个类的内部。

伴生对象(实现static关键字)

在Kotlin中是没有static关键字的,也就是意味着没有了静态方法和静态成员,在 Kotlin 中类没有静态方法。在大多数情况下,它建议简单地使用包级函数。如果确实需要,可以用伴生对象。

class A { 

	companion object coName(可以省略){ 

	//methods and fields 

	} 

}

实际上底层实现是把它当做静态内部类来看待的,并且目标类会持有该内部类的一个引用,那么最终调用的方法实际上是定义在这个静态内部类中的实例方法。

那么在伴生对象中定义的方法和包级别函数(顶层函数)有什么区别呢?而顶层函数则是作为一个包装类的静态方法出现的。如Test.kt里面有一个main方法,则会生成一个TestKt.class,而main方法则是这个类的静态方法。

类中的静态方法和内部类中的实例方法的区别,因为成员内部类中的方法是可以访问外部中定义的方法和成员的,哪怕是private的,而静态方法是做不到这一点的。

接口

既包含抽象方法的声明,也包含实现。这个跟Java8中提供的特性一样,但是Kotlin可是兼容到Java6的。相当于在老版本实现了高版本的功能。

在接口中声明的属性要么是抽象的,要么提供 访问器的实现。

From java to kotlin

考虑新的技术栈的应用除了带来的好处,还要考虑学习成本和迁移成本。Kotlin作为要兼容Java的公司,虽然语法上的区别有些大,但是总体来说迁移的成本还是非常低的。因为都是基于JVM的语言,各种库也可以混用。Spring也支持了Kotlin。

Java代码转换为Kotlin

作为JetBrains自家的语言,IDEA提供了非常棒的支持(虽然网上很多博客文章也提到IDEA对Kotlin的报错等支持很迷惑),比如方便Java代码转Kotlin,直接可以打开要转的java文件:

  • 快捷键 Ctrl+Shift+Alt+K 直接转换
  • 快捷键 Ctrl+Shift+A在搜索框输入Convert Java File to Kotlin或者
    Code ->Convert Java File to Kotlin

Kotlin代码转换为Java

大概需要转的kt文件

1、Tools->Kotlin->Show Kotlin Bytecode->Decompile

2、如果右侧有Kotlin Bytecode快捷图标,直接点即可

注意:一般情况下java转kotlin不会报什么错,但是从kotlin再转到java就要费事了

Kotlin中引用Java库

Kotlin 在设计时就考虑了 Java 互操作性。可以从 Kotlin 中自然地调用现存的 Java 代码,并且在 Java 代码中也可以很顺利地调用 Kotlin 代码。

几乎所有的java代码都可以使用而没有任何问题

import java.util.*

fun demo(source: List<Int>) {
    val list = ArrayList<Int>()
    // “for”-循环用于 Java 集合:
    for (item in source) {
        list.add(item)
    }
    // 操作符约定同样有效:
    for (i in 0..source.size - 1) {
        list[i] = source[i] // 调用 get 和 set
    }
}

详细

Java中调用Kotlin

Java 可以轻松调用 Kotlin 代码。 例如,可以在 Java 方法中无缝创建与操作 Kotlin 类的实例。 然而,在将 Kotlin 代码集成到 Java 中时, 需要注意 Java 与 Kotlin 之间的一些差异。

详细

更多例子from-java-to-kotlin

总结

因为仅仅处于资料学习阶段,没有真正使用过kotlin做项目,这篇文章更多的是笔者凭借目前知识和网络的评价做出的一些总结,因此也比较主观。

用一句话总结全文,那就是“Kotlin是一门值得学习的语言并且从Java转Kotlin的成本并不会太高”

Kotlin无疑是非常有潜力的语言。由于Kotlin出生较晚,可以很好的借鉴Java以及其他语言的各种优秀特性,所以非常对现在一线开发人员的胃口。毕竟是要抢占Java市场的语言,对Java的一些痛点抓的非常的准。而且语法糖层出不穷,用得上的时候真的非常顺手。

对于语法糖,我的感受是,不知道的时候可能没感觉,一旦用过可能就停不下来。例如我曾经写了很久的python再去写C++或者java就会觉得好难用。但是语法糖也可能会让整个系统变得比较复杂,比如前面属性扩展和函数扩展,可能会造成类的污染,也不利于开发人员之间的配合。而且debug的时候非常难受。追求优雅就需要技术的高超

另外,其实很多Kotlin的特性高版本的Java都是有的,奈何大部分公司还在使用Java8,并且Google大力支持Kotlin,Spring也出了Kotlin版本,可以说Kotlin也是收到了资本青睐的一门语言,未来的发展和生态也是值得期待的。而且Kotlin属于Kotlin基金会所有,此基金会由JetBrains与Google共同建立,此基金会致力于保护及推进Kotlin编程语言的发展,确保Kotlin始终是开源的,可见Google让Oracle的侵权官司吓坏了。

Kotlin的野心还不单单在于替代Java,Kotlin才支持了JavaScript,Multiplatform等平台。而且Kotlin还可以写脚本,现在连Gradle都官方支持了Kotlin脚本。其实从笔者个人角度觉得嚼多不烂,这种大面积的铺开更像是噱头,但是也可以彰显一下野心。

  • 1
    点赞
  • 1
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值