【问题标题】:Java object destructuringJava对象解构
【发布时间】:2019-10-28 09:04:42
【问题描述】:

在 javascript 中有对象解构,因此如果中间对象被多次重用,我们可以分解对象并仅使用结束键。例如)

const person = {
  firstName: "Bob",
  lastName: "Marley",
  city: "Space"
}

所以我们可以像这样解构它,而不是调用person.<> 来获取每个值

console.log(person.firstName) 
console.log(person.lastName) 
console.log(person.city) 

解构:

const { firstName, lastName, city } = person;

然后这样调用:

console.log(firstName)
console.log(lastName)
console.log(city)

Java 中有类似的东西吗?我有这个 Java 对象,我需要从中获取值,并且必须像这样调用长的中间对象名称:

myOuterObject.getIntermediateObject().getThisSuperImportantGetter()
myOuterObject.getIntermediateObject().getThisSecondImportantGetter()
...

我希望以某种方式对其进行解构,然后调用最后一个方法getThisSuperImportantGetter()getThisSecondImportantGetter() 以获得更简洁的代码。

【问题讨论】:

  • 你如何在Java中“解构”对象。有多种方法可以将字符串转换为属性,但没什么意义,或者您可以引入 jvm 脚本语言。无论哪种方式,您都会支付性能损失。或者您可以获取中间对象并以此为基础您的主线代码。当您进入嵌套对象时,“干净”通常与 Java 代码无关(并且可以说这样做可能有点粗略,具体取决于您需要能够轻松地修改/扩展代码,例如,Demeter )。
  • Java 并不以简洁或富有表现力而闻名。如果这些品质对您很重要,您可能想看看另一种 JVM 语言。
  • 不,它没有,但是您可以使用第一个 getter 的结果调用方法,然后在该方法内部使用内部对象。
  • 可以先将内部对象赋值给一个1字母的变量,然后调用a.getThisSuperImportantGetter()a.getThisSecondImportantGetter();

标签: java object destructuring


【解决方案1】:

Java 语言架构师Brian Goetz 最近谈到了在即将推出的 Java 版本中添加解构功能。在他的论文中寻找Sidebar:pattern matching一章:

Towards Better Serialization

我非常不喜欢当前的语法提议,但根据 Brian 的说法,您的用例将如下所示(请注意,此时这只是一个提议,不适用于任何当前版本的Java):

public class Person {
    private final String firstName, lastName, city;

    // Constructor
    public Person(String firstName, String lastName, String city) { 
        this.firstName = firstName;
        this.lastName = lastName;
        this.city = city;
    }

    // Deconstruction pattern
    public pattern Person(String firstName, String lastName, String city) { 
        firstName = this.firstName;
        lastName = this.lastName;
        city = this.city;
    }
}

您应该能够在 instanceof 检查中使用该解构模式,例如:

if (o instanceof Person(var firstName, lastName, city)) {
   System.out.println(firstName);
   System.out.println(lastName);
   System.out.println(city);
}

抱歉,Brian 在他的示例中没有提到任何直接的解构赋值,我不确定是否以及如何支持这些。

附带说明:我确实看到了与构造函数的预期相似性,但我个人不太喜欢当前的提议,因为“解构函数”的参数感觉像是外参数(布赖恩在他的论文中说了这么多)。对我来说,在一个每个人都在谈论不变性并让你的方法参数final 的世界里,这是相当反直觉的。

我宁愿看到 Java 越过栅栏,而是支持多值返回类型。大致如下:

    public (String firstName, String lastName, String city) deconstruct() { 
        return (this.firstName, this.lastName, this.city);
    }

【讨论】:

  • 一旦语言中内置了元组类型和解构,就会自动出现多个返回类型。
  • 值得注意的是,使用public record Person(String firstName, String lastName, String city){}将免费获得deconstruct。我同意 out 参数有点奇怪。
  • 只是好奇:你能举个例子 record 如何帮助解构吗?
  • 虽然解构声明的最终语法不固定,但已经给定记录将获得默认实现,类似于他们今天获得默认构造函数的方式。因此,使用记录声明,解构为与其组件匹配的变量将开箱即用。
【解决方案2】:

据我所知,java 不支持这个。

其他称为 Kotlin 的 JVM 语言确实支持这一点

Kotlin | Destructuring Declarations

【讨论】:

  • Clojure 也支持它,即使是嵌套结构,包括数组和映射。
猜你喜欢
  • 2023-03-21
  • 2020-06-14
  • 1970-01-01
  • 2016-06-11
  • 1970-01-01
  • 2021-06-23
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多