我相信我是在 1997 年开始使用 Java 的,也就是 Java 1.1 问世后不久。 从那时起,总的来说,我真的很喜欢用 Java 编程; 尽管我承认现在,我更有可能编写 Groovy 脚本,而不是用 Java 编写“严肃的代码”。
我之前使用过 FORTRAN、PL/1、Pascal,最后是 C,我发现 Java 有很多我喜欢的地方。Java 是我第一次重要的 面向对象编程 的实践经验。 那时,我已经编程了大约 20 年,并且可以肯定地说,我对什么重要,什么不重要有一些想法。
将调试作为关键语言特性
我真的很讨厌浪费时间来追踪那些由于我的代码不小心迭代到数组末尾而导致的模糊错误,尤其是在 IBM 大型机上用 FORTRAN 编程的那些日子。 另一个不时出现的微妙问题是用一个四字节的整数参数调用一个期望两个字节的子程序; 在小端架构上,这通常是一个良性错误,但在大端机器上,高两位字节的值通常(但并非总是)为零。
在批处理环境中进行调试也非常麻烦——仔细阅读核心转储或插入打印语句,这些语句本身可能会移动错误甚至使其消失。
因此,我早期使用 Pascal 的经验,首先是在 MTS 上,然后是在 IBM OS/VS1 上使用相同的 MTS 编译器,这让我的生活轻松了很多。 Pascal 的 强类型和静态类型 是这里获胜的重要因素,并且我使用的每个 Pascal 编译器都会插入运行时检查,以检查数组边界和范围,因此会在发生错误时立即检测到错误。 当我们在 20 世纪 80 年代初将大部分工作转移到 Unix 系统时,移植 Pascal 代码是一项简单的任务。
找到合适的语法量
但是,尽管我喜欢 Pascal 的所有优点,但我的代码很冗长,并且语法似乎倾向于略微模糊代码; 例如,使用
if … then begin … end else … end
代替
if (…) { … } else { … }
在 C 和类似的语言中。 此外,有些事情在 Pascal 中很难做到,但在 C 中却容易得多。 但是,随着我越来越多地使用 C,我发现自己遇到了与以前在 FORTRAN 中犯的相同类型的错误——例如,运行到数组的末尾——这些错误并没有在原始错误发生时被检测到,而只是在程序执行过程中通过其不利影响被检测到。 幸运的是,我不再生活在批处理环境中,并且手头有出色的调试工具。 尽管如此,C 给了我太多的自由,对我来说并不是一件好事。
当我发现 awk 时,我发现我有一个很好的 C 对应物。 当时,我的很多工作都涉及转换字段数据和创建报告。 我发现我可以用 awk 加上其他 Unix 命令行工具(如 sort、sed、cut、join、paste、comm 等)来完成令人惊讶的大量工作。 本质上,这些工具给了我一些非常类似于用于文本文件的关系数据库管理器,这些文本文件具有面向列的结构,这正是我们大量现场数据进来的方式。 或者,如果不是完全以这种格式,则大多数情况下,数据可以从关系数据库或某种二进制格式卸载到该面向列的结构中。
awk 支持的字符串处理、正则表达式 和 关联数组,以及 awk 的基本性质(它实际上是一个数据转换管道),非常适合我的需求。 当遇到二进制数据文件、复杂的数据结构和绝对性能需求时,我仍然会回到 C; 但是随着我越来越多地使用 awk,我发现 C 的非常基本的字符串支持越来越令人沮丧。 随着时间的推移,我最终只会不得已时才使用 C——并且可能会在其余时间里过度使用 awk。
Java 是合适的抽象级别
然后 Java 出现了。 从一开始它看起来就非常好——一种相对简洁的语法,让人想起 C,或者至少比 Pascal 或任何其他早期经验都更像。 它是强类型的,因此许多编程错误会在编译时被捕获。 似乎不需要太多的面向对象学习就可以上手,这是一件好事,因为当时我几乎不熟悉 OOP 设计模式。 但即使在最早的时候,我也喜欢其简化的 继承模型背后的想法。(Java 允许单继承,并提供接口来丰富该范例。)
而且它似乎附带了丰富的功能库(“电池已包含”的概念),这些功能库在适当的级别上工作,可以直接满足我的需求。 最后,我发现自己迅速喜欢上了数据和行为都分组在对象中的想法。 这似乎是显式控制数据之间交互的一种好方法——比巨大的参数列表或对全局变量的非受控访问要好得多。
从那时起,Java 逐渐成为我编程工具箱中的瑞士军刀。 我仍然会偶尔用 awk 编写一些东西,或者在 Linux 命令行实用程序(如 cut、sort 或 sed)显然并且精确地是解决手头问题的一种简单方法时使用它们。 不过,我怀疑在过去的 20 年里我是否编写过 50 行 C 代码; Java 已经完全取代了 C 来满足我的需求。
此外,Java 随着时间的推移一直在改进。 首先,它的性能变得更高。 它还添加了一些非常有用的功能,例如 try with resources,它可以很好地清理冗长且有些混乱的代码,这些代码用于处理文件 I/O 期间的错误处理; 或者 lambdas,它提供声明函数并将它们作为参数传递的能力,而不是旧方法,旧方法需要创建类或接口来“托管”这些函数; 或者 streams,它将迭代行为封装在函数中,从而创建一个高效的数据转换管道,该管道以链式函数调用的形式具体化。
Java 越来越好
许多语言设计者都在寻找彻底改善 Java 体验的方法。 对我而言,这些方法中的大多数目前还没有引起我很大的兴趣。 同样,这更多地反映了我典型的工作流程,(更少)是这些语言带来的功能的函数。 但是这些进化步骤之一已成为我编程武器库中不可或缺的一部分:Groovy。 当我遇到需要小型解决方案的小问题时,Groovy 已成为我的首选解决方案。 此外,它与 Java 高度兼容。 对我而言,Groovy 填补了 Python 为许多其他人填补的相同利基市场——它紧凑、DRY(不要重复自己)并且具有表现力(列表和字典具有完整的语言支持)。 我还利用 Grails,它使用 Groovy 为非常高性能且有用的 Java Web 应用程序提供简化的 Web 框架。
但是 Java 仍然是开源的吗?
最近,对 OpenJDK 日益增长的支持进一步提高了我对 Java 的舒适度。 许多公司都在以各种方式支持 OpenJDK,包括 AdoptOpenJDK、Amazon 和 Red Hat。 在我一个更大、更长期的项目中,我们使用 AdoptOpenJDK 来 在多个桌面平台上生成自定义运行时。
有没有比 Java 更好的语言? 我相信肯定有,这取决于您的工作需求。 但我仍然是一位非常开心的 Java 用户,并且我还没有看到任何威胁要将我带走的东西。
8 条评论