【问题标题】:Java: passing a new Class to a ConstructorJava:将新类传递给构造函数
【发布时间】:2022-01-12 19:03:14
【问题描述】:

我是 Java 新手,刚刚尝试了一些可行的方法,但我并不完全理解它。

public void test(){
    Employee employee = new Employee(new Date(1,2,1990));
}

我正在调用 Employee 的构造函数,然后 将一个新类作为参数传递并调用它的构造函数。这叫什么?我无法找到任何有关这方面的信息,并且想了解这里实际发生的情况。

更多细节:我的第一个尝试是创建 Date 类的实例,然后将对象作为参数传递,但为了节省代码和内存,我决定尝试这样做。它按我的预期工作,但我想了解它的对象生命周期,并知道这样做是否有任何缺点?

谢谢@hfontanez!搜索“匿名参考”帮助我找到了一些相关信息。但是没有太多可以解释的。

【问题讨论】:

  • “这叫什么?”它只是调用一个构造函数。
  • 没有专门的名称。您只是调用一个带有一个参数的构造函数。也就是说,您传递的是 Date 对象的匿名引用,因为您传递的实例没有(变量)名称。
  • 你调用一个构造函数,另一个对象是通过调用Date的构造函数作为参数创建的。
  • (附带说明,Date 已过时;您通常应该改用java.time.LocalDate。)
  • 我建议你不要使用Date。该课程设计不良且早已过时。而且即使你坚持使用Date,你也应该远离三参数构造函数。它已被弃用 25 年(大约),因为它跨时区工作不可靠。取而代之的是 @chrylis-cautiouslyoptimistic- 提到的使用来自 java.time, the modern Java date and time APILocalDate

标签: java parameters constructor parameter-passing


【解决方案1】:

您正在使用 'Date' 的实例调用 'Employee' 的构造函数,而创建 date 的实例意味着您正在使用 1,2,1990 调用 'Date' 的构造函数。

这会做同样的事情(我想这就是你的意思):

public void test() {
    // Create an instance of 'Date' by passing the arguments '1', '2' and '1990' to the constructor of 'Date'.
    Date date = new Date(1,2,1990);

    // Create an instance of 'Employee' by passing the argument 'date' to the constructor of 'Employee'.
    Employee employee = new Employee(date);
}

此代码与您发布的代码之间的唯一区别是您没有将创建的对象存储在代码中。

所以你不能像date.doAnything那样称呼它。

【讨论】:

  • 你的例子是我最开始做的,后来我修改它以减少代码和内存。而且我不再需要具有该信息的 Date 类的实例。
  • 如果您不需要它,您的方式是更有效的方式。但是你的问题现在回答了吗?
【解决方案2】:

唯一的区别是您在测试方法中没有对 Date 对象的引用,因此您将无法在测试方法中对其进行任何操作。除了将它传递给 Employee 对象之外,您似乎不需要对它做任何事情,所以没有理由不这样做。它不会影响 Employee 对象使用它的方式,因为 Employee 对象不知道也不关心 Date 参数是从变量传递还是匿名传递。

【讨论】:

    【解决方案3】:

    此代码创建一个新的日期对象并将其作为参数传递给 Employee 类的构造函数。日期对象可供以后使用。

    public void test(){
        Date date = new Date(1,2,1990);
        Employee employee = new Employee(Date);
    }
    

    此代码将匿名引用作为参数传递给 Date 类,作为 Employee 类的构造函数的参数。因此创建的日期对象只存在于构造函数的生命周期内,以后不能使用或引用。

    public void test(){
        Employee employee = new Employee(new Date(1,2,1990));
    }
    

    【讨论】:

    • “未创建日期对象”什么?当然是创建的。
    • 只存在于构造函数的生命周期,更好,但这取决于构造函数对它的作用。通常,它会将其分配给一个实例变量,在该变量中它的寿命比创建实例的代码长。
    【解决方案4】:

    使用各种词来描述代码的各个方面。正如您拥有Employee 对象的实例化一样,您也拥有设计不佳且早已过时的Date 类的对象的实例化。实例化产生的是对新创建对象的引用。在Employee 的情况下,您将此引用分配给一个变量,从而给它一个名称。由于您没有对 Date 引用进行此操作,因此其他人将其称为 匿名引用 是正确的。有些人也可能不太正式地谈论动态创建对象。它被传递给 Employee 构造函数,用于为构造函数的参数赋值,因此在构造函数内部不再是匿名的。

    优点和缺点

    你说

    ...为了节省代码和内存,我决定试试这个。

    最好尝试不同的选项,看看哪些有效,哪些无效,以及您认为最清楚地表达了您的意图并且更具可读性(对于其他读者,以及您在 6 个月后再次访问此代码时的您自己)忘记了一切)。你几乎没有节省任何内存。编译器通常足够聪明,无论您如何编写代码,都不会使用过多的内存。我的观点是:保存代码不应该是一个目标。您的目标是编写清晰、可读和可维护的代码,而不是编写少量代码。有时两者并存,因为通常阅读更少的代码比阅读更多的代码更容易。在您的情况下,一个明显的缺点就是您没有给日期命名。如果您将日期分配给名为 birthDate 的变量,您将告诉读者这是员工的出生日期。如果变量被称为hireDate,我们又知道了。根据您的代码,我们不知道员工和日期之间的关系是什么。

    java.time

    您的代码的现代和推荐版本是

    Employee employee = new Employee(LocalDate.of(1990, Month.FEBRUARY, 1));
    

    LocalDate.of() 是一个工厂方法,它创建一个新的LocalDate 对象。它通过在后台调用带有new 的构造函数来实现。

    只是为了强调您使用的 Date 构造函数是多么令人困惑,当我在亚洲/加尔各答时区运行您的代码时,它创建了一个 Date of Sat Aug 11 00:00:00 IST 1906。不要问为什么。只需停止使用该构造函数并完全停止使用Date

    链接: Trail: Date Time (The Java™ Tutorials) 解释如何使用 java.time。

    【讨论】:

    • 感谢您提供的信息。我将研究 java.time 类,但对于我正在玩的东西,我实际上创建了自己的 Date 类,它只保存 3 个整数,分别代表月、日和年。
    • 创建自己的Date 类是一个非常好的练习,鼓掌。对于生产代码,永远不会这样做。所以在你的代码中new Date(1,2,1990) 表示 1990 年 1 月 2 日?
    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 2014-06-04
    • 2018-05-09
    • 2013-04-23
    • 2023-04-04
    • 2015-10-11
    相关资源
    最近更新 更多