kotlin能取代java吗的最新相关信息

 我来答
zenki1984
2017-11-11 · TA获得超过1.5万个赞
知道大有可为答主
回答量:1357
采纳率:83%
帮助的人:390万
展开全部
我会建议使用纯JAVA。而不要去考虑Kotlin。否则,你将失去两大优势。
首先要搞清楚,kotlin与JAVA之间,其实并没有任何关系。kotlin是那个做IDE的Jetbrains公司创造的语言,它只和intellij IDEA这个IDE有关系。只是这个IDE,会在编译的时候,把kotlin转换成JAVA代码。所以kotlin无形中,便把使用者与这个IDE捆绑在了一起。而并不是与JAVA捆绑在了一起。

失去的第一个优势,便是从此无法自由选择IDE。。。对于kotlin来讲,将永远只有一个IDE可以选择。用户会成为Jetbrains公司的奴隶。如果有一天,你必须离开这个IDE,那你将会沦为废物,因为如果没有IDEA,kotlin无法做到任何事,哪怕仅仅一个“hello world”都不能。
失去的第二个优势则更加致命,也是JAVA可以获得成功的原因之一。。。JAVA能做的事情,其实很多其他语言也能做到。。但为什么JAVA可以如此受欢迎?除了JAVA本身的强大之外,还有一个原因在于,JAVA与C#语言,几乎是一模一样的。只有非常细微的差别,不仅语法一样,而且连编程思想都一样。只要掌握其中一门,完全可以在几天之内,无师自通另外一门。然后就可以对照api文档,去开发另外一门语言的程序了。所以学习JAVA的一大亮点就在于“学一门,会两门”。
C#很了不起吗?没错,非常了不起。。它本就可以视作JAVA获得成功的最大幕后英雄。。但我不是来讲故事的,因此微软与sun公司的恩怨情仇不在此深究。
我只说三个关键点,你自然明白其中利害关系。
1,它是微软的官方编程语言,微软的亲儿子,天生的富二代,Visual Studio便是为它量身设计。并且是微软唯一可以跨平台的儿子。。微软前不久又为它专门设计了轻量开发工具VS code。。不远的未来,它将成为微软的独子。未来几年,微软几乎全部工作都将与它有关。
2,它是游戏开发行业的第一大编程语言。占有60%以上的份额。Unity3D,CE5,寒霜,夜光,这四大游戏引擎的标准语言。《口袋妖怪Go》《使命召唤》《FIFA》《极品飞车》《最终幻想14》等数以万计的游戏都是由它开发而成。还包括国内最火的手游《王者荣耀》
3,它是虚拟现实(VR)设备开发的第一大语言。
扔掉JAVA,改用kotlin,也就等于与C#分道扬镳。。。所付出的代价,在我看来是无与伦比的。
动力节点
2019-05-10 · 口口相传的Java黄埔军校
动力节点
动力节点始于2009年,一家专注IT教育的培训机构,在全国各大城市设有直营校区,是中国软件研发人才一体化服务的倡导者,为解决当前软件开发技术飞速发展,专注培养面向互联网领域的IT高端软件人才
向TA提问
展开全部

原文:https://www.zhihu.com/question

毫无疑问,Kotlin 目前很受欢迎,业界甚至有人认为其将取代 Java 的霸主地位。它提供了 Null 安全性,从这一点来说它确实比 Java 更好。那么是不是这就意味着开发者应该毫不犹豫地拥抱 Kotlin,否则就落伍了?

但事实并非如此。

在开始使用 Kotlin 编程之前,本文想要分享个故事给你。在这个故事中,作者最早使用 Kotlin 来编写一个项目,后来 Kotlin 的各种怪异模式以及一些其他障碍越来越让人厌烦,最终,他们决定重写这个项目。

以下为译文:

一直以来,我对基于 JVM 的语言都非常情有独钟。我通常会用 Java 来编写主程序,再用 Groovy 编写测试代码,两者配合使用得心应手。

2017年夏天,团队发起了一个新的微服务项目,和往常一样,我们需要对编程语言和技术进行选型。部分团队成员是 Kotlin 的拥护者,再加上我们都想尝试一下新的东西,于是我们决定用 Kotlin 来开发这个项目。由于 Spock 测试框架不支持 Kotlin,因此我们决定坚持使用 Groovy 来测试。

2018年春天,使用 Kotlin 开发几个月之后,我们总结了 Kotlin 的优缺点,最终结论表明 Kotlin 降低了我们的生产力。

于是我们使用 Java 来重写这个微服务项目。

那么 Kotlin 主要存在哪些弊端?下面来一一解释。

名称遮蔽

这是 Kotlin 最让我震惊的地方。看看下面这个方法:

当你调用 inc(1) 会输出什么呢?在 Kotlin 中, 方法的参数无法修改,因此在本例中你不能改变 num。这个设计很好,因为你不应该改变方法的输入参数。但是你可以用相同的名称定义另一个变量并对其进行初始化。

这样一来,这个方法作用域中就有两个名为 num 的变量。当然,你一次只能访问其中一个 num,但是 num 值会被改变。

在 if 语句中再添加另一个 num,因为作用域的原因 num 并不会被修改。

于是,在 Kotlin 中,inc(1) 会输出 2。同样效果的 Java 代码如下所示,不过无法通过编译:

名字遮蔽并不是 Kotlin 发明的,这在编程语言中很常见。在 Java 中我们习惯用方法参数来映射类字段:

在 Kotlin 中名称遮蔽有些严重,这是 Kotlin 团队的一个设计缺陷。

IDEA 团队试图通过向每个遮蔽变量显示警告信息来解决这个问题。两个团队在同一家公司工作,或许他们可以互相交流并就遮蔽问题达成共识。我从个人角度赞成 IDEA 的做法因为我想不到有哪些应用场景需要遮蔽方法参数。

类型推断

在Kotlin中,当你声明一个var或是val,你通常会让编译器从右边的表达式类型中猜测变量类型。我们称之为局部变量类型推断,这对程序员来说是一个很大的改进。它允许我们在不影响静态类型检查的情况下简化代码。

例如,这个Kotlin代码:

Kotlin 编译器会将其翻译成:

Java 同样具备这个特性,Java 10中的类型推断示例如下:

实话实说,Kotlin 在这一点上确实更胜一筹。当然,类型推断还可应用在多个场景。关于 Java 10中的局部变量类型推断,点击以下链接了解更多:

https://medium.com/@afinlay/java-10-sneak-peek-local-variable-type-inference-var-3022016e1a2b

Null 安全类型

Null 安全类型是 Kotlin 的杀手级功能。

这个想法很好,在 Kotlin 中,类型默认不可为空。如果你需要添加一个可为空的类型,可以像下列代码这样:

假设你使用了可为空的变量但是并未进行空值检查,这在 Kotlin 将无法通过编译,比如:

那么是不是如果你同时拥有不可为空和可为空的变量,就可以避免 Java 中最常见的 NullPointerException 异常吗?事实并没有想象的简单。

当 Kotlin 代码必须调用 Java 代码时,事情会变得很糟糕,比如库是用 Java 编写的,我相信这种情况很常见。于是第三种类型产生了,它被称为平台类型。Kotlin 无法表示这种奇怪的类型,它只能从 Java 类型推断出来。 它可能会误导你,因为它对空值很宽松,并且会禁用 Kotlin 的 NULL 安全机制。

看看下面这个 Java 方法:

假如你想调用 format(String)。应该使用哪种类型来获得这个 Java 方法的结果呢?你有三个选择。

第一种方法:你可以使用 String,代码看起来很安全,但是会抛出 NullPointerException 异常。

那你就需要用 Elvis 来解决这个问题:

第二种方法:你可以使用 String,能够保证 Null 安全性。

第三种方法:让 Kotlin 做局部变量类型推断如何?

馊主意!这个 Kotlin 代码看起来很安全、可编译,但是它容忍了空值,就像在 Java 中一样。

除此之外,还有另外一个方法,就是强制将 f 类型推断为 String:

在我看来,Kotlin 的所有这些类似 scala 的类型系统过于复杂。Java 互操作性似乎损害了 Kotlin 类型推断这个重量级功能。

类名称字面常量

使用类似 Log4j 或者 Gson 的 Java 库时,类文字很常见。

Java 使用 .class 后缀编写类名:

Groovy 把类进行了进一步的简化。你可以忽略 .class,它是 Groovy 或者 Java 类并不重要。

Kotlin 把 Kotlin 类和 Java 类进行了区分,并为其提供了语法规范:

因此在 Kotlin 中,你必须写成如下形式:

这看起来非常丑陋。

反向类型声明

C 系列的编程语言有标准的声明类型的方法。简而言之,首先指定一个类型,然后是该符合类型的东西,比如变量、字段、方法等等。

Java 中的表示方法是:

Kotlin 中则是:

这种方法有几个原因令人讨厌。

首先,你需要在名称和类型之间加入这个多余的冒号。这个额外角色的目的是什么?为什么名称与其类型要分离?我不知道。可悲的是,这让你在 Kotlin 的工作变得更加困难。

第二个问题,当你读取一个方法声明时,你首先看到的是名字和返回类型,然后才是参数。

在 Kotlin 中,方法的返回类型可能远在行尾,所以需要浏览很多代码才能看到:

或者,如果参数是逐行格式的,则需要搜索。那么我们需要多少时间才能找到此方法的返回类型呢?

第三个问题是 IDE 中的自动化支持不够好。标准做法从类型名称开始,并且很容易找到类型。一旦选择一个类型,IDE 会提供一些关于变量名的建议,这些变量名是从选定的类型派生的,因此你可以快速输入这样的变量:

Kotlin 尽管有 IntelliJ 这样强大的 IDE,输入变量仍然是很难的。如果你有多个存储库,在列表中很难实现正确的自动补全,这意味着你不得不手动输入完整的变量名称。

伴生对象

一位 Java 程序员来到 Kotlin 面前。

“嗨,Kotlin。我是新来的,我可以使用静态成员吗?"他问。

“不行。我是面向对象的,静态成员不是面向对象的。” Kotlin 回答。

“好吧,但我需要 MyClass 的 logger,我该怎么办?”

“这个没问题,使用伴生对象即可。”

“那是什么东西?” “这是局限到你的类的单独对象。把你的 logger 放在伴生对象中。”Kotlin解释说。

“我懂了。这样对吗?”

“正确!”

“很详细的语法,”程序员看起来很疑惑,“但是没关系,现在我可以像 MyClass.logger 这样调用我的 logger,就像 Java 中的一个静态成员?”

“嗯......是的,但它不是静态成员!这里只有对象。把它看作是已经实例化为单例的匿名内部类。事实上,这个类并不是匿名的,它的名字是 Companion,但你可以省略这个名字。看到了吗?这很简单。"

我很欣赏对象声明的概念——单例很有用。但从语言中删除静态成员是不切实际的。在 Java 中我们使用静态 Logger 很经典,它只是一个 Logger,所以我们不关心面向对象的纯度。它能够工作,从来没有任何坏处。

因为有时候你必须使用静态。旧版本 public static void main() 仍然是启动 Java 应用程序的唯一方式。

集合字面量

在Java中,初始化列表非常繁琐:

初始化地图非常冗长,很多人使用 Guava:

在 Java 中,我们仍然在等待新的语法来表达集合和映射。语法在许多语言中非常自然和方便。

JavaScript:

Python:

Groovy:

简单来说,集合字面量的整齐语法就是你对现代编程语言的期望,特别是如果它是从头开始创建的。Kotlin 提供了一系列内置函数,比如 listOf()、mutableListOf()、mapOf()、hashMapOf() 等等。

Kotlin:

在地图中,键和值与 to 运算符配对,这很好。但为什么一直没有得到广泛使用呢?令人失望。

Maybe

函数式语言(比如 Haskell)没有空值。相反,他们提供 Maybe monad(如果你不熟悉monad,请阅读 Tomasz Nurkiewicz 的这篇文章:http://www.nurkiewicz.com/2016/06/functor-and-monad-examples-in-plain-java.html)。

Maybe 很久以前就被 Scala 以 Option 引入到 JVM 世界,然后在 Java 8 中被采用为 Optional。如今,Optional 是在 API 边界处理返回类型中的空值的非常流行的方式。

Kotlin 中没有 Optional 的等价物,所以你大概应该使用 Kotlin 的可空类型。让我们来调查一下这个问题。

通常情况下,当你有一个 Optional 的时候,你想要应用一系列无效的转换。

例如,在 Java 中:

在 Kotlin 中,为了映射你可以使用 let 函数:

上面的代码是错误的,parseInt() 会抛出 NPE 。map() 仅在有值时执行。否则,Null 就会跳过,这就是为什么 map() 如此方便。不幸的是,Kotlin 的 let 不会那样工作。它从左侧的所有内容中调用,包括空值。

为了保证这个代码 Null 安全,你必须在每个代码之前添加 let:

现在,比较 Java 和 Kotlin 版本的可读性。你更倾向哪个?

数据类

数据类是 Kotlin 在实现 Value Objects 时使用的方法,以减少 Java 中不可避免的样板问题。

例如,在 Kotlin 中,你只写一个 Value Object :

Kotlin 对 equals()、hashCode()、toString() 以及 copy() 有很好的实现。在实现简单的DTO 时它非常有用。但请记住,数据类带有严重的局限性。你无法扩展数据类或者将其抽象化,所以你可能不会在核心模型中使用它们。

这个限制不是 Kotlin 的错。在 equals() 没有违反 Liskov 原则的情况下,没有办法产生正确的基于价值的数据。

这也是为什么 Kotlin 不允许数据类继承的原因。

开放类

Kotlin 类默认为 final。如果你想扩展一个类,必须添加 open 修饰符。

继承语法如下所示:

Kotlin 将 extends 关键字更改为: 运算符,该运算符用于将变量名称与其类型分开。那么再回到 C ++语法?对我来说这很混乱。

这里有争议的是,默认情况下类是 final。也许 Java 程序员过度使用继承,也许应该在考虑扩展类之前考虑三次。但我们生活在框架世界,Spring 使用 cglib、jassist 库为你的 bean 生成动态代理。Hibernate 扩展你的实体以启用延迟加载。

如果你使用 Spring,你有两种选择。你可以在所有 bean 类的前面添加 open,或者使用这个编译器插件:

陡峭的学习曲线

如果你认为自己有 Java 基础就可以快速学习 Kotlin,那你就错了。Kotlin 会让你陷入深渊,事实上,Kotlin 的语法更接近 Scala。这是一项赌注,你将不得不忘记 Java 并切换到完全不同的语言。

相反,学习 Groovy 是一个愉快的过程。Java 代码是正确的 Groovy 代码,因此你可以通过将文件扩展名从 .java 更改为 .groovy。

最后的想法

学习新技术就像一项投资。我们投入时间,新技术让我们得到回报。但我并不是说 Kotlin 是一种糟糕的语言,只是在我们的案例中,成本远超收益。

以上内容编译自 From Java to Kotlin and Back Again,作者 Kotlin ketckup。

他是一名具有15年以上专业经验的软件工程师,专注于JVM 。在 Allegro,他是一名开发团队负责人,JaVers 项目负责人,Spock 倡导者。此外,他还是 allegro.tech/blog 的主编。

本文一出就引发了业内的广泛争议,Kotlin 语言拥护者Márton Braun 就表示了强烈的反对。

Márton Braun 十分喜欢 Kotlin 编程,目前他在 StackOverflow 上 Kotlin 标签的最高用户列表中排名第三,并且是两个开源 Kotlin 库的创建者,最著名的是 MaterialDrawerKt。此外他还是 Autosoft 的 Android 开发人员,目前正在布达佩斯技术经济大学攻读计算机工程硕士学位。

以下就是他针对上文的反驳:

当我第一次看到这篇文章时,我就想把它转发出来看看大家会怎么想,我肯定它会是一个有争议的话题。后来我读了这篇文章,果然证明了它是一种主观的、不真实的、甚至有些居高临下的偏见。

有些人已经在原贴下进行了合理的批评,对此我也想表达一下自己的看法。

名称遮蔽

“IDEA 团队”(或者 Kotlin 插件团队)和“Kotlin 团队”肯定是同样的人,我从不认为内部冲突会是个好事。语言提供这个功能给你,你需要的话就使用,如果讨厌,调整检查设置就是了。

类型推断

Kotlin 的类型推断无处不在,作者说的 Java 10 同样可以简直是在开玩笑。

Kotlin 的方式超越了推断局部变量类型或返回表达式体的函数类型。这里介绍的这两个例子是那些刚刚看过关于 Kotlin 的第一次介绍性讲话的人会提到的,而不是那些花了半年学习该语言的人。

例如,你怎么能不提 Kotlin 推断泛型类型参数的方式?这不是 Kotlin 的一次性功能,它深深融入了整个语言。

编译时 Null 安全

这个批评是对的,当你与 Java 代码进行互操作时,Null 安全性确实被破坏了。该语言背后的团队曾多次声明,他们最初试图使 Java 可为空的每种类型,但他们发现它实际上让代码变得更糟糕。

Kotlin 不比 Java 更差,你只需要注意使用给定库的方式,就像在 Java 中使用它一样,因为它并没有不去考虑 Null 安全。如果 Java 库关心 Null安全性,则它们会有许多支持注释可供添加。

也许可以添加一个编译器标志,使每种 Java 类型都可以为空,但这对 Kotlin 团队来说不得不花费大量额外资源。

类名称字面常量

:: class 为你提供了一个 KClass 实例,以便与 Kotlin 自己的反射 API 一起使用,而:: class.java为你提供了用于 Java 反射的常规 Java 类实例。

反向类型声明

为了清楚起见,颠倒的顺序是存在的,这样你就可以以合理的方式省略显式类型。冒号只是语法,这在现代语言中是相当普遍的一种,比如 Scala、Swift 等。

我不知道作者在使用什么 IntelliJ,但我使用的变量名称和类型都能够自动补全。对于参数,IntelliJ 甚至会给你提供相同类型的名称和类型的建议,这实际上比 Java 更好。

伴生对象

原文中说:

有时候你必须使用静态。旧版本 public static void main() 仍然是启动 Java 应用程序的唯一方式。

实际上,这不是启动 Java 应用程序的唯一方式。你可以这样做:

或者这样:

集合字面量

你可以在注释中使用数组文字。但是,除此之外,这些集合工厂的功能非常简洁,而且它们是另一种“内置”到该语言的东西,而它们实际上只是库函数。

你只是抱怨使用:进行类型声明。而且,为了获得它不必是单独的语言结构的好处,它只是一个任何人都可以实现的功能。

Maybe

如果你喜欢 Optional ,你可以使用它。 Kotlin 在 JVM 上运行。

对于代码确实这有些难看。但是你不应该在 Kotlin 代码中使用 parseInt,而应该这样做(我不知道你使用该语言的 6 个月中为何错过这个)。你为什么要明确地命名一个 Lambda 参数呢?

数据类

原文中说:

这个限制不是 Kotlin 的错。在 equals() 没有违反 Liskov 原则的情况下,没有办法产生正确的基于价值的数据。

这就是为什么 Kotlin 不允许数据类继承的原因。

我不知道你为什么提出这个问题。如果你需要更复杂的类,你仍然可以创建它们并手动维护它们的 equals、hashCode 等方法。数据类仅仅是一个简单用例的便捷方式,对于很多人来说这很常见。

公开类

作者再次鄙视了,对此我实在无话可说。

陡峭的学习曲线

作者认为学习 Kotlin 很难, 但是我个人并不这么认为。

最后的想法

从作者列举的例子中,我感觉他只是了解语言的表面。

很难想象他对此有投入很多时间。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友881abcb
2017-06-07 · TA获得超过186个赞
知道小有建树答主
回答量:262
采纳率:100%
帮助的人:123万
展开全部
并不可以,只是可供选项之一
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 2条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式