Java 语言的几个缺陷之五: 多返回值问题

希望 Java 能支持动态对象(匿名对象) 的特性是源于想要 Java 方法能优雅的返回多个值. 目前如果希望 Java 方法返回多个值的做法有返回一个自定义对象, 数组或列表, 或 Map. 这种需求多发生在私有方法上, 但目前的解决办法有如下弊端:

  1. 如果用自定义类来作为返回类型的话, 会使得类过于杂乱, 而且这些自定义类的复用性不高
  2. 数组或列表有太强的顺序依赖, 没有属性名告知每个位置上值的意义, 而且类型都必须为 Object
  3. 返回 Map 的, 在维护 Key 上容易出错(或须为 Key 定义很多字符串常量), 且类型也是为 Object.

说了上面许多, 各位可能还不定清楚我想要的是什么, 其实就是类似于 C# 的匿名对象(或曰动态对象), 看一段 C#  的方法返回一个匿名对象的例子(.NET3.5 开始引入匿名对象, .NET 4.0 后匿名对象可以作为函数值)

上面的代码输出为

Name: Yanbin, City: Chicago

注意: 对于方法返回的动态类型, 如 person, C# 编译器无法判断它有什么属性, 所以写 person.ab, person.bb 都能通过, 只会在运行期报错. 这就像返回 Map 的方法一样, 编译器是不知道某个 Key 是否存在的. 如果是在可见作用域下使用匿名对象编译器是可以检测属性是否存在, 如

很多其他语言的方法是通过  Tuple 来返回多个值, 在接收 Tuple 时可以进行拆解, 后面会说.

Play Framework 受到 Scala Tuple 的启迪, 它自己实现了几个 Java 版 Tuple(见 F.java), 包括 Tuple, Tuple3, Tuple4 和 Tuple5. 如果一个方法同时返回值不超过 5 个的话可以选择其中一种类型, 使用例子:

这就是 Java, 只能看到一大片的 ._1, ._2, 有时候一段代码要同时多个 Tuple, 于是一堆  person._1, customer._2, consumer._2, 这时就是眼花缭乱, 甚至是六神无主了.

假如换做其他几门语言

Scala (它有类库有 Tuple1, Tuple2, ..... Tuple22, 22  个类型来支持)

Swift(它在拆解 Tuple  时只与顺序有关)

Swift 的 Tuple 给属性命上名, 和 C# 的匿名对象基本是一样了.

JavaScript(ES6), JavaScript 都不干示弱了

Perl(与 Scala, Swift 语法差不多

Ruby(它是以数组形式返回多个值)

Python

Clojure(最近在学这个)

参考: 1. https://rosettacode.org/wiki/Return_multiple_values

本文链接 https://yanbin.blog/java-language-defect-no-multiple-returns/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments