【问题标题】:Can you instantiate a Java class constructor with an untyped object?你能用一个无类型的对象实例化一个 Java 类的构造函数吗?
【发布时间】:2018-08-05 07:29:28
【问题描述】:

我来自 Javascript 背景。我知道在Java中,要实例化一个类,您可以提供多个构造函数来设置类变量。但是,您能否为构造函数提供一个无类型对象来初始化类变量,如下所示:

public class Book {
    String title;
    String author;

    public Book(Object data) {
        this.title = data.title;
        this.author = data.author;
    }
}

我可以像这样实例化一个新的 Book 实例吗:

Book bookOne = new Book({ title: "Book One", author: "Author One" });

我之所以要这样做是因为如果一个类在初始化时有超过 10 个变量,那么通过给出一个假设为 10 个参数的列表来可靠地实例化一个类是很困难的。

【问题讨论】:

  • 不,你不能。 Object 没有 titleauthor 字段。
  • 那么这意味着如果我想在实例化过程中设置 10 个类变量,我将不得不创建一个接受 10 个参数的构造函数。这是正确的吗?
  • 技术上你可以,但你必须依靠反射来复制相关字段。这不是你通常在 Java 中工作的方式。
  • 在 Java 中,可以为此使用 Builder pattern。它可以让你写Book bookOne = new BookBuilder().setTitle("Book One").setAuthor("Author One").build()。您可以使用AutoValue 自动生成此类构建器。

标签: java class constructor


【解决方案1】:

您可以通过依赖 JSON api 并指定 String 而不是 Object 作为参数来做到这一点。
但这不是类型安全的,它是 Java 中强类型的反模式。
请注意,当您在 JavaScript 前端和 Java 后端之间进行通信时,当然可以接受在 Java 中接收 JSON。但一般我们不会直接操作 JSON。它在特定类的实例中反序列化,其中字段表示 JSON 传输的信息。

我想这样做的原因是因为如果一个班级让我们说 初始化时要超过 10 个变量,很难 通过给出一个比方说 10 的列表可靠地实例化一个类 参数

具有 10 个参数的类构造函数也不是一个好的模式。
虽然在某些情况下,为一个实例设置 10 个字段可能是可以接受的:尤其是当类仅代表一个数据结构时。
在这种情况下,设置对象字段的最佳方法是使用 setter 或 builder。

1) 二传手方式

Book b = new Book();
b.setTitle(...);
b.setAuthor(...);

2) 建造者方式

Book b = new Book.BookBuilder()
                 .withTitle(...)
                 .withAuthor(...)
                 .build();

但要真正避免容易出错的构造函数,因为可能会放错位置的参数类型以及构造调用的可读性也会受到影响。

【讨论】:

  • 我喜欢第二种我通常在这种情况下使用 lombok projectlombok.org/features/Builder
  • @YCF_L 出色的添加。就我个人而言,我不经常使用龙目岛,因为我喜欢为自己编写构建器,但我认为我必须停止这种情况:)
  • 很好地提到了我认为的构建器模式
  • 是的@davidxxx 你的代码可以像这样ideone.com/HdIejR ;)
  • @Sorakthun Ly 请注意,为类定义两个 setter AND 构建器在某种程度上破坏了构建器的意图:创建对象的一致性(状态、线程安全)和不变性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2011-04-04
相关资源
最近更新 更多