为什么要用Kotlin代替Java

我想告诉你一个名为Kotlin的新编程语言,以及为什么你应该为你的下一个项目考虑它。我曾经更喜欢Java,但去年我发现自己只要能够编写Kotlin,在这一点上我真的想不出Java会是一个更好的选择。

它是由JetBrains开发的,事实上这些是IDE套件背后的人,比如IntelliJ和ReSharper, 在Kotlin中真的很闪亮。它实用而简洁,使编码成为令人满意和高效的体验。

虽然Kotlin编译了JavaScript和很快的机器代码,但我将专注于它的主要环境,即JVM。
所以这里有几个原因你应该完全切换到Kotlin(没有特别的顺序):

0 # Java互操作性

Kotlin与Java可以100%互操作。使用Kotlin的时候我们可以继续使用老的Java库。你喜欢用的java第三方框架在kotlin项目中仍然可用,而且用kotlin写的框架同样可以用在Java项目中

1# 熟悉的语法

Kotlin并不是学术界的奇怪语言。任何来自面向对象编程的程序员都熟悉它的语法,并且可以从一开始就或多或少地理解它。当然,与Java有一些不同之处,例如重写的构造函数或val var变量声明。下面的代码段介绍了大部分基础知识

class Foo {
    
val b: String = "b"     // val 表示不可修改的变量
    
var i: Int = 0          // var 表示可以修改的变量
    
fun hello() {
        
val str = "Hello"
        
print("$str World")
    }
    
fun sum(x: Int, y: Int): Int {
        
return x + y
    }
    
fun maxOf(a: Float, b: Float) = if (a > b) a else b
}

2# 字符串插值

就好像String.format(),在Kotlin中内置了一个更智能,更易读的字符串格式化功能

val x = 4
val y =7
print("$x 和$y的总和是$(x+y)") // 4 和7的总和是11

3# 类型推断

Kotlin会在您认为可以提高可读性的地方推断您的类型:

val a =“abc”//类型推断为String 
val b = 4 //类型推断为Int 
val c:Double = 0.7 //明确声明类型
val d:List  = ArrayList()//明确声明类型

4# 智能类型转换

如果可能,Kotlin编译器会跟踪您的逻辑和自动转换类型。这意味着您不用在做instanceof判断之后做显示的类型转换

if(obj is String){
    print(obj.toUpperCase())//这里不用做显示类型转换
}

5# == 和 ===

== 等效于java中的equals(),=== 等效于java中的 ==

val john1 = Person("John")
val john2 = Person("John")
john1 == john2    // true  (structural equality)
john1 === john2   // false (referential equality)

6# 默认参数

方法有多个不同参数版本的时候,不需要定义多个重载函数

fun build(title: String,width: Int = 800,height: Int =600){
    Frame(title,width,height)
}

7#命名参数

结合默认参数,命名参数消除了对构建器的需求:

build("PacMan", 400, 300)                           // equivalent
build(title = "PacMan", width = 400, height = 300)  // equivalent
build(width = 400, height = 300, title = "PacMan")  // equivalent

8# When 表达式

使用when表达式代替switch

when (x) {
    1 -> print("x is 1")
    2 -> print("x is 2")
    3,4 -> print(x is 3 or 4)
    in 5..10 -> print("x is 5,6,7,8,9 or 10")
    else -> println("x is out of range")
}

而且when表达式可以赋值给变量

val res: Boolean = when {
    obj == null -> false
    obj is String -> true
    else -> throw IllegalStateException()
}

9# 属性

自定义的set和get方法可以添加到public字段,这意味着我们可以通过隐式的getter和setter来避免臃肿的代码

class Frame{
    var width: Int = 800
    var height: Int =600
    val pixels: Int
    get () = width*height
}

10# 数据类

使用java编写一个POJO,需要重写getter和setter,toString,equals等方法,在Kotlin中实现类似的功能十分简洁

data Persron(val name: String,var email: String,var age: Int)
val john = Person("John","[email protected]",24)

11# 运算符重载

可以重载预定义的一组运算符提高可读性

data Vec(val x: Float, val y: Float){
    operator fun plus(v: Vec) = Vec(x + v.x,y + v.y)
}
val v = Vec(2f,3f) + Vec(4f,1f)

12# 解构声明

一些对象可以被解构,特别是在遍历map的时候有用

for((key, value) in map){
    print("Key: $key Value: $value")
}

13# 范围

可读性秒杀java

for (i in 1..100) { ... } 
for (i in 0 until 100) { ... }
for (i in 2..10 step 2) { ... } 
for (i in 10 downTo 1) { ... } 
if (x in 1..10) { ... }

14# 扩展函数

还记得你第一次使用java给List排序吗?在List中你找不到sort方法。然后你不得不通过google学习Collections.sort()。

如果只有一种方法可以向旧类添加新函数; 这样您的IDE可以帮助您在代码完成中找到正确的功能。在Kotlin你可以做到这一点:

fun String.replaceSpaces(): String { 
    
return this.replace('','_')
} 
val formatted = str.replaceSpaces()

15# 空指针安全

在java中如果一个引用指向null,在使用该引用时可能会抛出NullPointException。在Kotlin中将引用分为两种非空类型和可空类型。默认的就是非空类型,可空类型在类型后面添加?

var a: String = "abc"//默认非空类型
a = null //编译报错

var b:String? = "xyz"//可空类型
b = null //没问题

无论何时访问可空类型,Kotlin都会强制您防范NPE:

val x = b.length //编译错误:b可能为null

虽然这看起来很麻烦,但由于它的一些功能,它真的很轻松。我们仍然有智能强制转换,它会尽可能地将可空类型转换为非null:

if(b == null)return
val x = b.length //没问题

我们也可以使用安全调用?.,其值为null而不是抛出NPE

val x = b?.length // x的类型是可以为空的Int

安全调用可以链接在一起,以避免我们有时用其他语言编写的嵌套if-not-null检查,如果我们想要一个默认值,null我们可以使用elvis运算符?::

val name = ship?.captain?.name?:“unknown”

如果这些都不适合您,并且您绝对需要NPE,则必须明确要求:

val x = b?.length?:throw NullPointerException()//与下面相同
val x = b!!.length //与上面相同

16# 更好的Lambdas

在可读性和简洁性之间完美平衡,这得益于一些聪明的设计选择。语法首先是直截了当的

val sum = {x:Int,y:Int  - > x + y} // type:(Int,Int) - > Int 
val res = sum(4,7)// res == 11

这里有聪明的一点:

  1. 如果lambda是方法的最后一个或唯一参数,则可以移动或省略方法括号。
  2. 如果我们选择不声明单个参数-lambda的参数,它将在名称下隐式声明it。

这些事实相结合,使以下三行等效:

numbers.filter({x  - > x.isPrime()})
numbers.filter {x  - > x.isPrime()} 
numbers.filter {it.isPrime()}

这使我们能够编写简洁的功能代码

persons
    .filter {it.age> = 18} 
    .sortedBy {it.name} 
    .map {it.email} 
    .forEach {print(it)}

你可能感兴趣的:(kotlin)