接触了一些新语言后,回头看Java8之后的更新

date
Nov 30, 2020
slug
接触了一些新语言后,回头看Java8之后的更新
status
Published
tags
Java
summary
Java一直被认为是一门啰嗦的语言,有个段子是调侃一个小项目,用Java写就会变成大项目。但Java同时也使用广泛,工程性强,写Java的人也是最多。对Java的这些特点,在没写过太多其他语言之前,我的认识很肤浅,有点人云亦云的感觉。在最近因为工作原因写了大量go、Javascript、TypeScript代码之后,再回头来看Java,居然没有像常见到的那些写了go就不想碰Java的观点一样感到轻松,而是十分怀念…
type
Post
Java一直被认为是一门啰嗦的语言,有个段子是调侃一个小项目,用Java写就会变成大项目。但Java同时也使用广泛,工程性强,写Java的人也是最多。对Java的这些特点,在没写过太多其他语言之前,我的认识很肤浅,有点人云亦云的感觉。在最近因为工作原因写了大量go、Javascript、TypeScript代码之后,再回头来看Java,居然没有像常见到的那些写了go就不想碰Java的观点一样感到轻松,而是十分怀念…
下面梳理一下Java8之后的主要变化,再聊聊为什么我怀念写Java

Java 9

JEP 213: Milling Project Coin

Interface中允许实现私有方法:
Java8中就有把一些工具类方法放到Interface中而不是一个空的Class里的实践,当时这种做法有个缺点,就是Class可以有私有方法,可以选择暴露哪些接口,隐藏哪些接口,而使用Interface只能写一些相对简单的逻辑,因为所有方法都会暴露。
现在Interface和Class的区别更明显了,Interface更像是一个没有状态的更灵活的Class,工具类的方法没有理由再写在Class中了。
try-with-resources的写法优化:
try-with-resources的写法可以帮我们自动释放资源,减少了模版代码,增强了可读性。但在try-with-resources声明多个变量时,可读性就会下降,例如:
Java 9之后我们可以这样写,可读性有了明显提高:
单独的下划线(_)不再是合法的变量名:
在许多语言中,如果一个变量名是_,那么通常表示这个变量不重要,可以忽略;显然设计者Java中也出现这种用法,现在把这条路彻底堵死了,即把设计往前提,从API层面就返回void,而不是返回了一个值,却去忽略它。

Java 11

JEP 323: Local-Variable Syntax for Lambda Parameters

Java允许用var声明本地变量了:
不用声明参数类型,类型由编译器去推断。这是我比较不喜欢的一个改动,社区的说法是:
We seek to improve the developer experience by reducing the ceremony associated with writing Java code, while maintaining Java’s commitment to static type safety.
显然,社区是为了开发者写的时候能少点模版代码,提升开发体验。虽然这个改动非常克制,即只能用于声明本地变量,理论上来说,如果代码都是短方法组成的,声明的地方和使用的地方很近,那么这个改动就无关紧要。但现实是业务逻辑中由于各种原因,经常能见到成百上千行的遗留代码,经年累月往上叠加逻辑,不是重构基本没人愿意去动它。如果加上一堆var变量,对本来就糟糕的可读性来说无疑是雪上加霜了…
所以想要升级到Java 11的团队,最好做好代码规范和CR吧,不要等到屎山已经形成了才想到可维护性。

Java 14

JEP 361: Switch Expressions

新的switch写法:
我个人非常喜欢这个改动,值得多写几笔来聊聊这个改动。这个改动并不是像上面的演示一样,仅仅是支持箭头操作符、yield关键字这么简单。还有以下几个重要的改变
  1. 新的switch没有fall-through这个特性了,不用再写一大堆break;不会再遇到由于漏掉某个break;而产生的诡异bug。要知道甚至还有一些教程里有利用fall-through特性的演示代码,这对可读性和可维护性简直就是个灾难!(说的就是你
  1. 每个case支持了自己的作用域 ```java String s = switch (k) { } ```
    1. 支持多个条件合并了,只要用逗号隔开即可 ```java enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }
      1. Day day = Day.TUESDAY; switch (day) { case MONDAY -> “:(”; case TUESDAY, WEDNESDAY, THURSDAY -> “:|”; case FRIDAY -> “:)”; case SATURDAY, SUNDAY -> “:D”; } ```
    1. switch可以当作一个表达式来用了: ```java int k = 3; System.out.println(
      1. ); ```
    1. 要求switch语句是exhaustive的,不知道怎么翻译,意思就是对于case类型是字符串或者其他原生类型的,必须要定义default分支。这就进一步在编译阶段消灭了潜在的问题。
    之前Java的switch写法一直饱受诟病,在我的实践中,如果不是万不得已,我都是不愿意用switch写分支结构的,经过这次修改之后,在写分支的时候,我甚至会优先考虑是不是可以用switch来写。Java社区对switch的修改,在我看来是非常成功的修改。

    Java 15

    JEP 378: Text Blocks

    Java支持了多行字符串:
    在整理到这个特性的时候,我都有点恍惚,一是因为工作中需要直接写多行字符串的场景不多,另一个是别的语言中基本都支持三引号的多行字符串,Java居然到15才支持?总之,来得晚也比不来强,在一定要手写字符串的场景下,以前的写法明显可读性差远了,可维护性也差远了
    简单的说,NPE的报错会变成这样
    这简直是福音,又是一个我特别喜欢的改动,NPE有可能是每个Java开发者碰到最多的问题了…之前出现的时候,排查还是挺难的,不熟悉代码的情况下甚至需要一个一个去试。现在报错就直接告诉你了,真的很棒

    为什么怀念写Java

    1. 准确的说不是怀念写Java,更准确的说法是怀念读Java。实际上写起来爽的话,go写起来确实很爽…但是工作中并不是只要写代码,我发现工作的重心越来越多的转移到读代码、改代码,不过是同事的代码还是开源项目,读代码的时候就会发现读Java的代码有多么轻松,写的时候的那些麻烦,读的时候都变成了贴心的提示。
    1. 怀念Java强大的IDE(IDEA),对比写JavaScript和TS的时候,总是有一种心虚的感觉,代码不跑一跑心里就没底…
    1. 因为死板,奇淫巧技就少,碰上一群喜欢“炫技”又追求“
    1. Self-documenting code”(指不写注释)的同事,你就知道我在说什么了…
    总之,Java确实进步慢,确实老,但显然Java社区知道要往哪里走,绝大多数改动都改在心坎里,让人受用。甚至我认为作为一个技术人员,也要学会“扬长避短”,不要盲目求新,打好基础,认清自己的方向更加的重要。

    © oddcc 2020 - 2024