不服来战,看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似乎是未来几年移动开发领域最有希望的赢家。

翻译原文:https://dzone.com/articles/why-kotlin-language-android-why-did-google-choose

原文发布于微信公众号 - CSDN技术头条(CSDN_Tech)

原文发表时间:2017-11-23

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏转载gongluck的CSDN博客

黑暗的内存管理

黑暗的内存管理 很多人对 C 语言深恶痛绝,仅仅是因为 C 语言迫使他们在编程中必须手动分配与释放内存,然后通过指针去访问,稍有不慎可能就会导...

42460
来自专栏章鱼的慢慢技术路

2015年第六届蓝桥杯C/C++B组省赛题目解析

23820
来自专栏小樱的经验随笔

【请您听我说】PHP语法特点的一些看法

一、基本认识   PHP是干什么的?百度百科上提到说:PHP就是一门脚本语言,开发用的,相信这个你们只要去搜一下,就会有一大堆关于PHP概念的解释。   相信我...

37360
来自专栏java一日一条

关于 Java 的10个谎言

下面的这些都算是比较高级的问题了,面试中一般也很少问到,因为它们可能会把面试者拒之门外。不过你可以自己找个时间来实践一下。

8010
来自专栏清晨我上码

第二节 DDD领域部分

一般只有领域层负责领域模型,其他层为其服务,这设计的好处是将领域相关的代码分离开来 具体每层的含义不再赘述。

12420
来自专栏韩伟的专栏

框架设计原则和规范(一)

此文是《.NET:框架设计原则、规范》的读书笔记,本文内容较多,共分九章,将分4天进行推送,今天推送1-3章。 1. 什么是好的框架 2. 框架设计...

46650
来自专栏Android群英传

我与 Kotlin 的爱恨情仇之浅谈 block

13540
来自专栏Java技术栈

6 道 BATJ 必考的 Java 面试题

请对比 Exception 和 Error,另外,运行时异常与一般异常有什么区别?

11410
来自专栏java一日一条

程序中减少使用if语句的方法集锦

大约十年前,我听说了反if的活动,觉得这个概念非常荒谬。如果不用if语句,又怎么能写出有用的程序呢?这简直太荒谬了。

17320
来自专栏瓜大三哥

HLS Lesson19-函数层面优化

1.Coding Style on function 主要是数据类型,应该定义为HLS专用的数据类型ap_int<W> 2.inline:去除了函数的层次化,...

23890

扫码关注云+社区

领取腾讯云代金券