Java与C ++中的对象数组

时间:2015-09-20 12:18:33

标签: java arrays

我的背景是C ++,在c ++中,我们可以使用简单的语法轻松创建对象数组。 className obj[n];以及构造函数将调用n时间。

但是当我尝试在java className[] obj=new className[n];中创建对象数组时没有构造函数调用。在搜索之后,我在stackoverflow找到了这个问题的答案,它只是创建了n可以指向n个对象的参考,我需要为每个参考再次创建对象。 obj[0]=new className();

现在我只想问为什么java会这样做?有什么理由甚至C ++允许但java不允许以相同的方式创建对象数组? 我搜索了这个,但仍然没有得到确切的答案。

4 个答案:

答案 0 :(得分:9)

在C ++中,您可以灵活地选择创建对象的内存。您可以在自动区域(堆栈中),静态区域或动态区域中创建对象。在最后一种情况下,您将获得一个对象指针,并在完成后负责释放它。

相比之下,所有Java都是动态区域选项,因为所有对象都是引用对象。在C ++中,它等同于仅通过指针使用对象,并始终使用new创建它们。在C ++中执行此操作时,还必须使用new - ed对象填充指针数组:

myclass *array[10];
for (int i = 0 ; i != 10 ; i++) {
    array[i] = new myclass();
}
...
for (int i = 0 ; i != 10 ; i++) {
    delete array[i];
}

允许在C ++中创建对象数组是一种选择,需要让程序员在自动区域中分配对象数组。它带来了权衡,因为您从中创建数组的对象必须具有默认构造函数。这并不理想,因为默认构造函数的要求听起来是任意的。

另一方面,Java不受自动内存要求的限制,所以他们选择了一个简单的解决方案,要求你单独初始化对象。

答案 1 :(得分:3)

通常不需要使用默认构造函数创建与数组相同类型的对象。有时您想调用自定义构造函数。有时您想要实例化子类并将它们存储在数组中。

请注意,Java数组className[] obj更像是C ++数组className* obj[n],而不仅仅是className obj[n],因为它是对象的引用数组,而不是对象本身的数组。从Java-8开始,你不能自己创建一个对象数组(它们作为project Valhalla的一部分进行讨论,但即使在Java-9中也不会出现)。当对象本身以C ++存储在数组中时,必须初始化数组。你不能在那里保留“nulls”或类似的东西,因为null不是一个对象,它是引用(或指针)。当您在C ++中创建className* obj[n]数组(更类似于Java className[] obj数组)时,它也是未初始化的。

最后请注意,在Java-8中,您可以使用默认构造函数轻松创建实例化它们的所有对象,如下所示:

className[] array = Stream.generate(className::new).limit(n).toArray(className[]::new);

答案 2 :(得分:2)

允许或不允许的是语言设计者。

如果要初始化Array的所有元素,并引用Java中的同一对象,则可以使用:

className[] obj = new clasName[2];
Arrays.fill(obj, new className());

或创建不同的对象并为每个构造函数传递不同的参数

className[] obj = new className[] {new className(), new className()};

答案 3 :(得分:1)

在Java中,无论何时声明变量,无论是对象还是局部变量的成员,它都是基本类型(bytechar,...)或者是引用类型(指向某种类型的对象的指针) 因此,没有对象数组,只有引用数组。

在C ++中,你有自由和责任选择你做了多少间接,如何分配,释放,构建和销毁对象,增加了很多复杂性:

  • dereference-operator(*pointer
  • dereference-and-use-member(pointer->member
  • 运营商地址(&object
  • 从其他类型(type* var)派生指向类型的指针的方法。
  • placement-new(`new(pointer)type(arg1,arg2);
  • 显式删除操作符(delete pointer
  • 更多。