kotlin的一些特性介绍和与java C#的简单对比
前言
这是我之前在知乎上的一些回答的汇总,感觉还是博客园写这些东西方便一点,也算是理下我的一些思路,现将文章整理后,发布在园子里。
为何是kotlin:
很多人对kt没有一个正确的定位,可能大家第一反应是拿它去和scala,groovy比较.
从语法的角度而言,kotlin丰富且严谨到恰到好处的语法糖,表达能力强但不啰嗦,极少的代码冗余。
但老实讲能做到这些的语言也不算少,单看语法,事实上kt比scala还是要略差一筹的,
他们都是非常优秀的jvm语言,总体来说是难分伯仲,kt也没办法将他们甩出一个身位.
但我必须得说,绝大部分情况下(指常规开发),如果你选择kt作为你的第二jvm语言,比用scala,groovy等,
开发工程中的收益要多的多的多...成本亦低的多的多的多(注意我不是单单在说语言层面了)
首先,最重要也是让kotlin与其他jvm语言有本质不同的地方在于:无缝和java程序的衔接以及极低的交互成本。
- 老项目想尝新?在maven或gradle里面加个配置,就能开写kotlin了.
- 不敢直接用?先用来写UT啊,UT写顺了,你自然会忍不住想继续写。
- 已有java代码怎么办?直接用啊,封装都不用,两者可以直接调用,智能提示也都在,反过来kotlin写的库java同样能用。
kotlin的一些典型特征:
静态强类型
这个不多说,java,C#,kotlin都是典型,稍微上点规模的项目,都应该用静态强类型来打底子。TypeScript越来越火也可见一般。
当然我不是说静态就优于动态,这是看场景的,比如需求相对复杂和稳定的后端和随业务迅速迭代的前端,他们的技术诉求肯定就不一样。
比如做gateway,我就觉得动态类型的语言更适合,参考阿里的node.js使用场景。
学习成本
其实大家回忆下学习语言的过程,是花在语法上的时间多,还是花在熟悉标准库上的时间多?
而kotlin则完全没有后者的成本,time还是用的joda,http还是Apache的HttpClient,或者OkHTTP,
也会纠结netty,tomcat,akka 的方案选型,同样需要注意集合类的时间复杂度和线程安全情况。
可以说在熟悉java生态的前提下学习kt,成本是非常低的。
其实我给人安利时候,一般给C#的人说Kotlin,就是“jvm届的C#”
给Java的人说:“你别把它当新语言,你就把他当Java9”,当然9现在已经发布了,我可以换成10了,哈哈。
学习新语言总是会给人带来一些压力,但也要注意语言和语言之间的学习成本的不同,
我曾开玩笑说:我学习scala(入门)花的功夫,足够我学会js,php,python这三门语言了。
而kt的低成本高收益,才是我对它如此推崇的最大原因。
生态支持
最后,也是最重要的优势:jetBrains爸爸全方位无死角超贴心的配套支持
(画外音:用过Resharper,IDEA,WebStorm,PyChrome的朋友,让我看到你们的双手!!)
熟悉jetBrain的朋友,应该能够感觉到,这是一家非常有特色和魅力的公司,其在ide和pl工程领域的积累,大家应该也心里有数.
j系ide都有一个特点,就是对开发者极其友好,
基于语法(AST?)而非文本的代码分析,带来的超高的智能提示准确率和极度便利的重构,
对可能的异常代码的警告和解决方案的提示.jetBrains总是倾向于让开发者写出严谨又简洁且鲁棒的代码。
幸运的是,kt也继承了爸爸的这些特质,不仅仅是语法的严谨,还体现在了开发过程中。
比如maven配置,java交互,nullable的注解提示,idea配套插件.
而且kt是他们内部很早就立项的语言,他家的各路ide都是用kt写的。
各种插件个ide的支持,基本可以和语言版本同步迭代。
说了这么多文字,且废话占多数,想必大家也有点烦了,那我下面就以java和kt的比较为切入点,介绍一些kt的特点吧。
其实就是过一遍 Kotlin/kotlin-koans,建议有兴趣的可以clone个玩玩。
val 定义的变量不可变
var 同C#,val和var都是隐式强类型推断,
val的作用在于,我前面定义一个orderState,即表示,这个变量就只做取值用途,你别再拿来干别的事情了,避免了一值多用的bad small.
默认参数,及参数名传参:
减少无意义多态的使用,但又比js的一值多用直观的多.
labmda写法改进
必须在一个花括号中,如果以lambda为参数,可省略(),看起来很舒服
如果只有一个参数,则可以省略声明,用it代替,(同scala的 _ )
scala的一个参数对应的_只能出现一次,第二个_代表第二个参数,更简洁的写法但带来更模糊的语义,孰优孰劣不谈,但两者的风格差异在这个细节中可见一斑.
nullable
kt对null pointer 问题非常敏感,任何可能的npr都需要显示的处理,如果不处理,nullable会一直往后传染并给出一个警告,
这时候你要么用!!表示我tm确定这里肯定不为null,要么用?:表示如果为空,则表达式的值为后面提供的缺省值. 这个设计基本和C#那边的一样
tems是订单详情的集合,详情包含ActualWeight,但未发生实提则为null,如果是传统写法,需要先判断find出来的是否是null,再判断这个find是否有实提,如果有则返回实提,没有则返回double 0(lambda可省略return)
大家可以体会下这省了多少工夫?
扩展方法,
这是我觉得所有静态语言都应该提供的特性,原理非常简单,但带来的写法上的优化非常有价值
kt和C#扩展方法原理大致类似,就是this作为第一个参数传给静态方法的一个语法糖,但kt不要求强制定义在一个静态方法中
表示所有的string实例,在lastChar的可访问范围内,都多了一个成员函数,其实就是
static StringHelper.lastChar(str:String)
的变种,在不支持em的java看来,就长刚才这个样子,用起来就是如下形式:
H3.em3(H2.em2(Helper1.em1(what)))
low爆了是吧? 下面是我封装的一个操作poi的代码
next是移动到下一单元格,设置样式是复制第一行的样式,其实还可以封装,为了显示表达出我的操作意图,这里就留着了.
说到这里就差不多了,再说也就是抄袭koans,也没啥大的意思了,最后扯点其他的作收尾吧.
谈一谈我对语法糖的看法:
我个人对语法糖的评价是非常高的,也许这个糖的原理并不复杂,比如我之前提到的扩展方法,但我们认识它的原理是远远不够的,还得理解,为什么要有这玩意.
H3.em3(H2.em2(Helper1.em1(what))) VS what.em1().em2().em3()
上面后者省略了import H1 H2 H3的过程,综合起来工作量也没差太多
但真的就仅仅是写法和视觉上的优化吗?其实远远不止.
前者是,XXHelper里面有个方法,可以操作what这个类型并做一些事情,
后者是,what既然有这样的特质,那么它就应该拥有某样的能力
前者是思维先找到Helper,再找到具体方法,
后者是what自然而然的提示出,what就有这样的能力(ide的智能提示),我敲下what+ . 后,它的能力就展示在我面前了,而不需要我还去翻箱倒柜的找helper方法.
谈谈激进技术的风险和收益,与不同阶层人员关注点的不同.
我最早推进kt的时候,最大的阻力就是来自公司的架构师团队,他们的关注点是:
kt相比java,能提高性能吗?(不能,kt的性能与java极度接近但略小与java)
kt解决了什么java并不能解决的问题吗?(没有,kt只是让你更快更好的写java代码)
kt能减少项目bug,提高项目稳定性吗?(某种程度上来说有一定帮助,但更多是看人,这理由也不够强力)
那时候我只是个开发 leader,这种层面肯定是没有太大的决策权的,他们的想法我也理解,公司几百号开发,提高一点点效率,相比引入新技术栈的风险,肯定是稳定压倒一切啦.
后面在我的争取下,我在一个简单项目上少量使用kotlin作为试点,后来一些原因我离开了这个公司,去小公司当技术合伙人去了,现在那段kotlin代码应该还跑在公司的tomcat上面,其他人不去翻代码,他们也不会知道这是用kotlin写的吧?
kotlin的一些特性介绍和与java C#的简单对比的更多相关文章
- Kafka2.4发布——新特性介绍(附Java Api Demo代码)
新功能 允许消费者从最近的副本进行获取 为 Consumer Rebalance Protocol 增加对增量协同重新均衡(incremental cooperative rebalancing)的支 ...
- Java与C++简单对比
Java语言让编程者无法找到指针来直接访问内存,并且增添了自动的内存管理功能,从而有效的组织了C/C++语言中指针操作失误,如滥用指针所造成的系统崩溃,Java的指针在虚拟机内部使用,这保证了Java ...
- java各版本简单对比
1995.5 Oak ——>java1.0 提出 write once run anywhere 1996.1 jdk1.0 jvm Sun Classic VM 1997.2 JDK1.1 ...
- 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小
原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...
- java定时调度器解决方案分类及特性介绍
什么是定时调度器? 我们知道程序的运行要么是由事件触发的,而这种事件的触发源头往往是用户通过ui交互操作层层传递过来的:但是我们知道还有另外一种由机器系统时间触发的程序运行场景.大家想想是否遇到或者听 ...
- Java 11 新特性介绍
Java 11 已于 2018 年 9 月 25 日正式发布,之前在Java 10 新特性介绍中介绍过,为了加快的版本迭代.跟进社区反馈,Java 的版本发布周期调整为每六个月一次——即每半年发布一个 ...
- Java 12 新特性介绍,快来补一补
Java 12 早在 2019 年 3 月 19 日发布,它不是一个长久支持(LTS)版本.在这之前我们已经介绍过其他版本的新特性,如果需要可以点击下面的链接进行阅读. Java 11 新特性介绍 J ...
- spider RPC框架的需求来源与特性介绍(一)
spider RPC 特性介绍 spider RPC 性能测试 spider RPC 入门指南 spider RPC 配置文件参考 spider RPC 开发指南 spider RPC 安全性 spi ...
- dubbox新特性介绍
dubbx是当当网对原阿里dubbo2.x的升级,并且兼容原有的dubbox.其中升级了zookeeper和spring版本,并且支持restfull风格的远程调用. dubbox git地址: h ...
随机推荐
- SCAU Individual Contest #1
总结一下就是自己太弱.每次打比赛遇到比较难题就喜欢瞎开题,结果都是每题想一下,然后就是结束了. A:题意让你用小写字母构造一个总共有K个的回文串,比如aba的话就是{a}{b}{a}{aba}四个,比 ...
- java web 数据库开发1
一个完整的数据库部署架构通常由客户端和服务器端两部分组成.客户端封装数据库请求将其发送给服务器端,服务器端执行完毕将其及结果返回给服务器端. 以mysql为例 介绍java应用程序对数据库的访问 JD ...
- kafka 0.10.2 消息生产者
package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.KafkaProducer; import org ...
- sql导出
第一步: 要求:把Library里面的Readers表导出到MyDB中(注意:读者编号.设置了主键)
- 初入计算机图形学(二):对bidirectional path tracing的一些困惑
本人水平有限,若有错误也请指正~ 前文提及了光线追踪的一些常用手法,但是其中path tracing的实现最为简单,但是其最致命的一个缺点就是图像收敛速度很慢..原因在于从摄影机发射出的每一条光线若不 ...
- JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表
一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...
- 【easyui】Tab的tools按钮刷新当前tab
点击刷新按钮,刷新当前Tab选项卡 /** * Name 选项卡初始化 */ $('#home-tabs').tabs({ tools: [{ iconCls: 'icon-reload', bord ...
- Expression 转化为sql(三) --自定义函数
SQL 语句有很多函数如len(),now()等等.如何来生成这些函数.最近研究也写办法共大家参考. 一.首先建立一个建一个扩展类,控制只能允许这些函数出现,如果出现其他函数就直接报异常. publi ...
- CSS 公共样式
global.css | reset.css(格式化样式) common.css(公共组件样式) layout.css(当前页面样式) 清除全站所有页面的浏览器默认样式,保证在初始样式在所有浏览器下一 ...
- [转] .NET领域驱动设计—初尝(疑问、模式、原则、工具、过程、框架、实践)
阅读目录: 1.1.疑问 1.1.1.UML何用 1.1.2.领域建模 1.2.模式 1.3.原则 1.5.过程 1.6.框架 1.7.项目演示 最近在研究DDD颇有收获,所以整理出来跟大家分享,共同 ...