【问题标题】:How do I allocate array of objects in Java?如何在 Java 中分配对象数组?
【发布时间】:2015-10-02 09:33:38
【问题描述】:

到目前为止,在阅读一些 Java 教程时,我一直在使用以下语法分配数组:

// Ok, all the elements are zero upon creation
int[] a = new int[5];

// I can set all the elements however I want!
for (int i = 0; i < a.length; i++)
     a[i] = i+1

但是自从我开始使用一个类之后,事情就让我很困惑:

class Employee
{
    public Employee(String name, int age) {
         emp_name = n;
         emp_age = a;
    }

    void setName(String name) {
          emp_name = name;
    }

    void setAge(int age) {
          emp_age = age;
    }

    private String emp_name;
    private String emp_age;

}

我在主函数中使用这个类,如下所示:

Employee[] staff = new Employee[3];

这一行应该给我一个由三个对象组成的数组,默认由构造函数初始化。

当我执行以下操作时,运行时出现异常。

staff[0].setName("Test");

在 C++ 中,这非常简单,不需要额外的new

Employee *e[3];

因此,在进一步搜索后,我发现我仍然需要为数组中的每个元素分配内存才能真正开始使用它们。如果是这样,那么使用new 运算符的目的是什么?它不是已经为数组分配内存了吗?为什么int 数组不会发生这种情况?

【问题讨论】:

  • Employee[] staff = new Employee[3]; 是一个大小为 3 的 Employee 数组,可以容纳三个 Employee 实例。 int[] a = new int[5]; 是一个包含 5 个 int 的原始整数数组。没有什么不同,只是使用方式不同。
  • 请删除 C++ 标签,因为您的问题不是关于 C++,而是关于 Java。 Java 和 C++ 是不同的语言,处理数组的方式也不同。

标签: java arrays


【解决方案1】:

当您创建对象数组时,您会创建一个包含null 对象的数组。阵中充满了“虚无”。在您明确创建 Employee 之前,不会创建 Employee

Employee[] staff = new Employee[3];

此时你的数组看起来像:

[空] [空] [空]

然后您可以通过以下方式创建员工:

staff[0] = new Employee();

此时,您的默认 Employee 构造函数被调用,并且您的数组现在在第一个位置有一个 Employee 对象:

[Employee1][null][null]

现在您在第一个位置有一个实际的Employee,您应该可以调用:

staff[0].setName("Test");

更新:

关于问题:

使用 new 运算符的目的是什么?它不是已经为数组分配内存了吗?为什么 int 数组不会发生这种情况?

herehere 已经提出了类似的问题。简而言之,当您创建对象数组时,您实际上创建了一个引用数组。起初,所有这些引用都只是指向空对象。当你做staff[0] = new Employee();时,你本质上是在做两件事:

  1. 为“新”员工创建和分配内存
  2. 告诉staff[0] 现在指向新的Employee 对象而不是null

【讨论】:

    【解决方案2】:

    在 Java 中,所有“对象”实际上都只是引用(指针之类的)。所以你假设Java自动初始化数组中的值是正确的,但是在你的第二个数组中,你有一个引用数组,它们基本上是内存地址,因此被初始化为null

    你得到你的异常是因为你在 null 引用上调用了一个方法。另外,请注意,当您创建一个基元数组时,您正在使用具有数组中不同索引的赋值运算符。在您的对象示例中,您只是立即使用数组中的值,而不是分配它们。所以从技术上讲,你在原始数组示例中所做的可以使用对象数组来完成,因为它是简单的赋值。

    【讨论】:

    • Java 使用引用,而不是指针。 There are differences.
    • 我知道有区别,但基本上可以一视同仁,而且由于@cpx 谈到了 c++ 和指针,我认为将引用比作指针会帮助他更好地理解。
    • 特别是如果他/她有 C/C++ 背景,不建议使用错误的术语。人们可能会假设不正确的事情(例如“指针算术和内存重新解释是可能的”)。
    • 在 C++ 中,new 的目的始终是分配一些内存。考虑声明 Employee[] staff = new Employee[3]; 让我有点困惑,因为它没有分配任何东西。它只是声明一个数组而不对内存做任何事情。那么,如果我认为它只是分配一个引用数组,因为它们存在于堆上,因此我们使用 new 运算符,我是否正确?当我第一次查看代码时,我觉得好像我正在创建一个二维数组,即首先为数组创建 new 运算符,然后为数组中的每个元素创建 new
    • @cpx 您认为“它只是分配引用数组,因为它们位于堆上,因此我们使用new 运算符”是正确的。声明 Employee[] staff = new Employee[3]; 告诉 JVM “给我一个对 Employee 对象的引用数组”。声明中没有任何地方说要给你真正的雇员;您需要在其他语句中告诉 JVM 这样做。
    【解决方案3】:

    在 Java 中,当您创建对象数组时,数组中每个条目的默认值都是 null。没有调用构造函数。您必须遍历数组并为每个条目创建一个对象。

    例如

    for(int i=0; i<staff.length; i++){
        staff[i] = new Employee("name" + i, 20);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-17
      • 2019-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 2021-07-24
      相关资源
      最近更新 更多