我想知道为什么用Java静态创建数组,即使我们使用new
关键字来定义它。
根据我的阅读,new关键字在运行时遇到堆时会在堆中分配一个内存空间,所以为什么在定义期间根本不给出数组的大小。
e.g。为什么不能
int[] array1=new int[20];
简单地说:
int[] array1=new int[];
我知道它不会自动增长,我们已经为此ArrayList
了,但是关键字new
的用法是什么?它可以被定义为int array1[20];
,就像我们以前在C,C ++中一样,如果它必须是静态的。
P.S。我知道这是一个业余的问题,但我是一个业余爱好者,我试图谷歌,但找不到任何全面的。
答案 0 :(得分:2)
这可能是一个业余的问题,但它是你可以做的最好的业余问题之一。
为了让java允许你声明没有new
的数组,它必须支持一种额外的数据类型,它在某种意义上表现得像一个原语,它不需要分配,但它在某种意义上它将与大小不同的原语非常不同。这会使编译器和JVM变得非常复杂。
java采用的方法是提供最小和最小的原语,以便能够有效地完成大部分工作,并使用对象完成其他所有操作。这就是数组是对象的原因。
另外,你可能会对这里的“静态”含义感到困惑。在C中,“静态”表示“文件范围”,即其他目标文件不可见。在C ++和Java中,“静态”意味着“属于类”而不是“属于类的实例”。因此,术语“静态”不适合描述数组分配。 “固定大小”或“固定的预定义大小”将是更合适的术语。
答案 1 :(得分:2)
好吧,在Java中,一切都是对象,包括数组(它们有length
和其他数据)。这就是为什么你不能使用
int var[20];
在java中int
,编译器会混淆。而是使用这个:
int[] var;
您声明var
的类型为int[]
(int数组),因此Java了解它。
同样在java中,数组的长度和其他数据都保存在数组中,因此你不必在声明期间声明数组的大小,而是在创建数组时(使用new
)数据已保存。
也许有一个更好的理由,oracle可能已经回答了,但是在Java中,一切都是对象的事实必须与它有关。 Java对于对象和类型非常具体,不像C,你有更多的自由,但一切都更松散(特别是使用指针)。
答案 2 :(得分:1)
由于数组是固定大小的,因此需要知道在实例化时要分配多少内存。
内部使用数组存储数据的ArrayLists或其他调整大小数据结构实际上在内部数组数据时重新分配更大的数组 结构填满了。
答案 3 :(得分:1)
数组数据结构的主要思想是它的所有元素都位于连续的存储单元行中。这就是为什么你不能创建具有可变大小的数组的原因:为了这个目的,它应该在内存中没有空间矢量,这是不可能的。
如果要更改数组的大小,则应重新创建它。
答案 4 :(得分:1)
我对OP推理的理解是:
new
用于分配动态对象(可以像ArrayList
那样增长),但数组是静态的(无法增长)。因此,其中一个是不必要的:new
或数组的大小。
如果这是问题,那么答案很简单:
嗯,在Java new
中,每个Object分配都是必需的,因为在Java中,所有对象都是动态分配的。
事实证明,在Java中,数组是对象,与C / C ++不同,它们不是。
答案 5 :(得分:0)
所有Java变量最多只能是一个64位字段。像
这样的基元integer
(32位)long
(64位)或对依赖于JVM / config / OS的对象的引用是64或32位字段(但不同于保证原子性的64位原语)。
没有C' int[20]
"类型"。也没有C&#39静态。
归结为int[] array = new int[20]
的内容大致是
int* array = malloc(20 * sizeof(java_int))
每当您在Java中看到new
时,您可以想象malloc
以及对构造函数方法的调用,以防它是真正的Object
(而不仅仅是数组)。每个Object
或多或少只是一些原语和更多指针的结构。
结果是一个巨大的网络,相对较小的结构指向其他东西。垃圾收集器的任务是释放掉掉网络中的所有叶子。
这也是为什么你可以说Java是按值复制的原因:原语和指针总是被复制。
关于Java中的static
:每个类在概念上都有一个表示类的静态上下文的结构。这是static
实例变量锚定的地方。非静态实例变量以其自己的instance-struct
class Car {
static int[] forAllCars = new int[20];
Object perCar;
}
...
new Car();
非常松散地翻译(我的C很可怕)到
struct Car-Static {
Object* forAllCars;
};
struct Car-Instance {
Object* perCar;
};
// .. class load time. Happens once and this is referenced from some root object so it can't get garbage collected
struct Car-Static *car_class = (struct Car-Static*) malloc(sizeof(Car-Static));
car_class->forAllCars = malloc(20 * 4);
// .. for every new Car();
struct Car-Instance *new_reference = (struct Car-Instance*) malloc(sizeof(Car-Instance));
new_reference.perCar = NULL; // all things get 0'd
new_reference->constructor();
// "new" essentially returns the "new_reference" then