我相信我从 1997 年开始使用 Java,那时 Java 1.1 刚刚问世后不久。 从那时起,总的来说,我非常喜欢用 Java 编程;尽管我承认现在,我更可能编写 Groovy 脚本,而不是用 Java 编写“严肃的代码”。
我之前使用 FORTRAN、PL/1、Pascal,最后是 C。我发现 Java 有很多优点。Java 是我第一次重要的面向对象编程的实践经验。 那时我已经编程了大约 20 年,可以肯定地说我对什么重要,什么不重要有一些想法。
将调试作为关键语言特性
我真的很讨厌浪费时间去追踪由于我的代码不小心迭代到数组末尾而导致的晦涩的错误,特别是在 IBM 大型机上用 FORTRAN 编程的时代。 另一个不时出现的微妙问题是用一个四字节的整数参数调用一个需要两字节的子程序;在小端架构上,这通常是一个良性错误,但在大端机器上,高位两个字节的值通常(但并非总是)为零。
在这种批处理环境中进行调试也很尴尬 - 仔细研究核心转储或插入打印语句,这些语句本身可能会移动错误,甚至使它们消失。
因此,我早期在 MTS 上,然后在使用相同的 MTS 编译器在 IBM OS/VS1 上使用 Pascal 的经验,使我的生活变得轻松了许多。 Pascal 的 强类型和静态类型是其中的一大优势,而且我使用过的每个 Pascal 编译器都会对数组边界和范围进行运行时检查,因此可以在发生时检测到错误。 在 1980 年代初期,我们将大部分工作转移到 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 的时候才使用 C - 并且可能在其余时间里过度使用 awk。
Java 是合适的抽象级别
然后 Java 就出现了。 从一开始看起来就非常好 - 一种相对简洁的语法,让人联想到 C,或者至少比 Pascal 或任何其他早期经验更像 C。 它是强类型的,因此许多编程错误会在编译时被捕获。 它似乎不需要太多的面向对象学习即可上手,这是一件好事,因为那时我对 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 条评论