不服来战,看Kotlin如何完爆Java

Posted GitChat精品课

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不服来战,看Kotlin如何完爆Java相关的知识,希望对你有一定的参考价值。

前言:Kotlin因支持谷歌和简化android开发而声名鹊起。看看它如何解决Java的许多痛点。

Why Kotlin?


如果我今天被问到如何区别开发Android应用程序与其他领域开发时,我会毫不犹豫地回答,以原生方式在不同硬件上执行相同应用程序可能会是其中原因之一;但…这怎么可能?我想我还是通过解释Kotlin语言的好处来开始我的这篇文章吧。

在这一点上,没有人惊讶地看到相同的web应用程序运行于任何设备,任何平台(Android、ios、 Windows、MacOS…)。我们都知道这些应用程序比任何本地应用程序都更慢,也更不稳定,但是优点是,我们只需要为所有平台开发一个应用程序。Java的强悍之处在于如今它已经应用于数十亿的设备上,无论其硬件和软件如何,只要它有一个Java编译器生成的pseudo-compiled解释器。

但是,这是否意味着Java是完美的解决方案?不幸的是,事实并非如此。尽管Java解决了设备之间的互操作性问题,但它带来了一系列新的问题,以下便是其中一些:

注意:这些问题虽然在Java 8和9中得到了解决,但在API 24以下的Android SDK中是不可用的,这使得它们实际上无法使用。

对于optionals没有本地支持:虽然有Optional 类,但它的使用意味着生成大量的样板代码,如果对选项的支持是在语言本身内构建的,而不是扩展的,我们可以保存这些代码。

对于函数式编程,没有本地的支持:在Java中,有Stream API (再说一次,它只支持从API 24开始的Android),但是它在语言中的集成类似于Optional;它不存在于与原始类型相关联的对象中(IntStream,DoubleStream…),并且通过一个Stream class 提供给所有其他对象。

支持匿名函数(Lambdas):尽管Java 8包含了对Lambda函数的支持,但这些都不是一级公民;这意味着,尽管我们可以使用lambdas以单个方法实现匿名接口,但Java不支持将函数作为参数传递给方法。另外,由于在语言中缺乏对它们的支持,类型推断的缺失使得Lambdas的语句非常不舒服,特别是在试图模拟函数比如函数组合或局部套用时。

Type nullability:虽然这可以包含在可选的部分中,但是这个问题的维度应该特别提到。有多少Java程序员试图通过if (foo! = Null)与可怕的NullPointerException斗争,而没有填满他们的代码?(事实上,它的创建者应该为他所说的“十亿美元的错误”道歉),而这些检查中有多少是为了避免在我们的应用程序中出现崩溃而做出的补丁呢?

Binding of manual views:尽管这个问题是针对Android平台的,而不是针对Java的,但它也需要样板代码,以获得对Android视图的引用。尽管我们已经通过dataBinding成功地消除了不受欢迎的findViewById(int id),但我们仍然需要存储对该绑定的引用。

为什么Kotlin 会打破这一切


Java是一种非常冗长的语言,它需要为任何操作编写大量的代码,并生成大量的文件(每个类一个)。第一个问题可能会导致我们代码的维护成本更高,更容易出现错误。第二个问题是 class proliferation问题。

正是由于这些原因,今天,Java被认为至少在Android开发中,并没有以行业的速度发展。随着时间的流逝,需要有一种现实和原生支持的语言来解决所有上面提到的问题变得越来越必要,这种语言需要同时拥有我在本文开头提到的主要特点:编写和编译一个应用程序,使它可以运行在任何设备和版本上。

在这个方向上,许多可能性已经被探索,其中一些是使用Swift或Scala,尽管没有一个是非常有希望的。所有这些都随着Kotlin语言的出现而改变。Kotlin是由Jetbrains设计和开发的一种语言,这种语言还在不断的进化中,最重要的是,它可以在JVM上执行。这使它成为Android应用的完美候选者。

为了证明这一点,我们可以列出在面对Java的所有缺点时,Kotlin表现出的优势:

Optionals:他们被构建在Kotlin;你所要做的就是声明一个变量的类型以问号结尾,这样它就变成了optional的类型。Kotlin还提供了安全打开那些optionals listener ?.onSuccess() 的可能性,而无需检查optional有没有值,并且还提供了Elvis Operator。

函数式编程:在Kotlin中,我们找到了本地支持来处理像Streams这样的集合和数据集。我们可以在一个collection中直接调用 .flatMap {}或者.filter {}、.map {}等等。类型的推断使得使用Lambdas变得特别容易。

Lambdas和高阶函数:在Kotlin中,函数是一级公民的事实已经完成。我们可以定义接收其他函数作为参数的函数。一个例子是map函数本身的定义:

虽然乍一看,这段代码看起来有点混乱,我们感兴趣的部分是transform:(T)- > R .这意味着map函数有一个参数transform,这本身就是一个函数,它有一个T类型的输入参数,并返回一个对象类型的R。

由于本地对lambdas的支持,在Kotlin中,我们可以使用map函数:

inline fun <T, R> Iterable.map(transform: (T) -> R): List (source)

此代码片段将返回由aTransformation生成返回类型的元素集合。

collection.map { item -> aTransformation(item) }

Type nullability:在Kotlin中,由于有对optionals的集成支持,我们的代码中应该有最小可能的nullables。但即便如此,Kotlin还是提供了比Java更容易处理的工具。例如,我们有safe call (?) 来避免NullPointerException,或者在我们想要执行转换时使用操作符安全的cast来保护我们。另外,Kotlin的编译器强制控制可能具有空值的类型,甚至在与Java代码兼容的情况下引入运行时检查。

Binding of views:这是一个具体的Android问题,Jetbrains为我们提供了Kotlin Android扩展;一个官方的支持库通过一个gradle的插件来简化这个问题(以及其他一些问题)。

Java:

public interface Listener {
  void success(int result);
  void error(Exception ex);
}
public void someMethod(Listener listener) {
  int rand = new Random().nextInt();
  if(listener != null) {
    if (rand <= 0) {
      listener.onError(new ValueNotSupportedException());
    }
    else {
      listener.success(rand);
    }
  }
  public void fun(Type1 param1) {
    param1.someMethod(new Listener() {
      @Override
      public void success(int result) {
        println(“Success” + result);
      }
      @Override
      public void error(Exception ex) {
        ex.printStackTrace();
      }
    }
}


Kotlin:

fun someMethod(success: (Int) -> Unit, error: (Exception) -> Unit) {
    val rand = Random().nextInt()
    if (rand <= 0) {
        error(ValueNotSupportedException())
        else {
            success(rand)
        }
    }
}
fun (param1: Type1) {
    param1.someMethod( {
        println(“Success” + it);
    }, {
        it.printStackTrace();
    })
}


或者使用表达式: 

fun someMethod(success: (Int) -> Unit, error: (Exception) -> Unit) {
    val rand = Random().nextInt()
    if (rand <= 0) error(ValueNotSupportedException()) else success(rand)
}
fun (param1: Type1) {
    param1.someMethod( {
        println(“Success” + it);
    }, {
        it.printStackTrace();
    })
}


现在,读者应该很清楚,哪一个片段更容易编写和解释。

以上,我们所讨论的,以及许多其它的功能,都在不断的证明,Kotlin似乎是未来几年移动开发领域最有希望的赢家。


以上是关于不服来战,看Kotlin如何完爆Java的主要内容,如果未能解决你的问题,请参考以下文章

Netty,最火事件驱动网络框架,不服来战?

源码大招:不服来战!撸这些完整项目,你不牛逼都难!

「仅限100人」10天LeetCode100题,不服来战!

单例模式绝对没有你想象的那么简单!不服来战!

Redis只能做缓存?这10道面试题难倒一大片,不服来战!

csp模拟赛1不服来战 (challenge.cpp)