专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
码农翻身  ·  团队准备解散了 ·  2 天前  
程序员小灰  ·  又一个职业要被AI淘汰了! ·  4 天前  
51好读  ›  专栏  ›  OSC开源社区

“Effective Java” 对 Kotlin 设计的影响 — Part 1

OSC开源社区  · 公众号  · 程序员  · 2017-01-19 08:36

正文


Java 是一门非常不错的编程语言,但也存在一些缺陷,部分缺陷从 1995 年的早期版本延续至今。在 Joshua Bloch 出版的 Effective Java 一书中,作者详细介绍了避免常见编码错误及处理的方式。它包含 78 项,从语言的不同方面给读者提供了宝贵的意见。


Jetbrains,一家捷克的软件开发公司,于 2010 年创建了编程语言 Kotlin。该语言消除了 Java 中存在的一些问题,更简洁也更易表达。


重读 Effective Java 时,我发现许多建议对 Kotlin 来说都不那么必要了,所以,在这篇文章中,我想总结性地介绍一下这本书是如何影响 Kotlin 的设计的。


 Kotlin 的默认值不需要更多构建器


当 Java 的 constructor 中存在多个可选参数时,代码会变得冗长,难读且容易出错。为解决这一问题,Effective Java 在第 2 项中介绍了如何有效的使用构建器模式。


此类对象的构建需要用到许多代码,如下面代码示例中的 Nutrition 成分对象,它包含两个必须的参数(servingSize, servings)和四个可选参数(calories, fat, sodium, carbohydrates):


用 Java 实例化对象,如下所示:


使用 Kotlin,则不需要使用构建器模式,因为有默认参数的功能,你可以为每个可选构建函数参数定义默认值:


在 Kotlin 中创建一个对象,如:


为了实现更佳的可读性,你还可命名所需的参数 servingSize 和 servings:


和 Java 一样,此处创建的对象不可变。

我们将代码行数从 Java 中的 47 减少到了 Kotlin 的 7,从而有效提高了生产力。

提示:如果要在 Java 中创建 KotlinNutrition 对象,我们可以这样做,但是必须为每个可选参数指定一个值。幸运的是,如果添加 JvmOverloads 注解,则会生成多个构造函数。 注意,如果要使用注解,则需要关键字 constructor:



 轻松创建单例模式


Effective Java 的第 3 项介绍如何将 Java 对象设计为单例,它实际上是一个对象,其中只有一个示例可以实例化。下列示例进行了演示,其中只有一个 Elvis 存在:


Kotlin 有对象声明的概念,它给我们提供了一个单例的行为:


完全不用手动构建!:)


equals() 和 hashCode() 开箱即用


函数式编程和简化代码的良好实践,主要是为了使用不可变值对象。第 15 项中给出了建议:“除非有可变的合适理由,否则类不可变。”Java 中的不可变值对象非常繁琐,因为对于每个对象,你都必须重写 equals() 和 hashCode() 函数。


Joshua Bloch 花了 18 页来描述如何遵守第 8 项和第 9 项提到的约束。例如,如果你重写 equals(),你必须保证反身性,对称性,传递性,一致性和非零性的约束都得到满足。这听起来更像是数学而不是编程。


在 Kotlin 中,你可以简单地使用数据类,编译器会自动派生 equals() 和 hashCode() 等方法。这是可以实现的,因为标准功能可以机械地从对象属性导出,你只需在类前输入关键字 data 即可。


提示:最近,Java 的 AutoValue 开始流行起来,这个库为 Java 1.6+ 生成不可变的值类。


属性而非字段



第 14 项建议在公共类中使用访问器方法而不是公共字段。如果不这么做的话,可能会引来一堆麻烦,因为字段之后可直接访问,这样以来你就无法享受封装和灵活性带来的好处。


这也意味着,如果不更改类的公共 API,你将无法更改其内部表示。例如,你无法限制字段的值,如员工的年龄等。这也是我们在 Java 中创建默认 getter 和 setter 的原因之一。


这个最佳实践由 Kotlin 强制执行,因为它有自动生成默认 getter 和 setter 的属性而不是字段。


在语法上,您可以使用 person.nameor person.age 访问 Java 中的公共字段等属性,稍后再添加自定义 getter 和 setter,而无需更改类的 API:


小结:使用 Kotlin 的属性,我们可以得到更简洁的类,具有更大的灵活性。


重载必须关键字而不是可选注释


Java 1.5 中添加了注释,其中最重要的一个是 Override,它标志着一个方法重载了超类的一个方法。第 36 项介绍说,这个注释用以避免恶性 Bug。当你认为你在重写超类中的一个方法,但实际上并不是的时候,编译器将抛出一个错误。只要你别忘记写 Override 注解,它就能起作用。


在 Kotlin 中,override 不是可选注解,而是必须关键字,所以 Bug 出现机会不多。 

(未完待续)


原文:How “Effective Java” may have influenced the design of Kotlin — Part 1

责任编辑:开源中国 — 达尔文





推荐阅读

2016 年度开源中国新增开源软件排行榜 TOP 100

2016 年度最受欢迎中国开源软件 TOP 20

2016 年度码云热门项目排行榜 TOP 50

2017 值得关注的十个开源项目

2017 最值得关注的十大 APP、Web 界面设计趋势

点击“阅读原文”查看更多精彩内容