简体   繁体   English

零长度数组如何在内存中表示?

[英]How is the zero length array represented in memory?

The Java primitive objects are mapped to native primitives. Java原始对象映射到本机基元。
So my question is how is a char value[] = new char[0]; 所以我的问题是char value[] = new char[0];是多少char value[] = new char[0]; is being represented? 有代表吗?
Does it depend on the gcc compiler implementation (of the native code)? 它是否依赖于gcc编译器实现(本机代码)? Would that mean that all empty Java String s point to the same address? 这是否意味着所有空的Java String指向同一个地址?

Memory layout is undefined because it is an implementation detail. 内存布局未定义,因为它是一个实现细节。

Here's how IBM describes the memory layout of an array for their 64bit JVM: 以下是IBM如何为其64位JVM 描述数组的内存布局

  1. 64 bits for a class pointer (ie signalling char ) 64位用于类指针(即信令char
  2. 64 bits for flags (eg saying that this object is an array) 标志的64位(例如,说这个对象是一个数组)
  3. 64 bits for lock data (for synchronization) 锁定数据的64位(用于同步)
  4. 64 bits for array length (only 32 bits are used, but the field is boundary aligned) 数组长度为64位(仅使用32位,但字段是边界对齐的)
  5. 0 bits for data, since the array has no elements 数据为0位,因为数组没有元素

That's a total of 256 bits or 32 bytes. 这总共是256位或32个字节。

In Java, a String and a char[] are not the same thing. 在Java中, Stringchar[]不是一回事。 A String will be a separate object containing a reference to a char[] . String将是一个单独的对象,包含对char[]的引用。

Java arrays are objects. Java数组是对象。 They inherit from the Object class. 它们继承自Object类。

The JVM spec does not dictate any particular implementation for objects, provided they behave according to the specs. JVM规范没有规定对象的任何特定实现,前提是它们的行为符合规范。 In practice, it is implemented with a header followed by the actual fields of the object. 在实践中,它使用标题后跟对象的实际字段来实现。

An array in Java is not just a sequence of its primitive components. Java中的数组只是它的原始成分的序列。 It is an object, it has the length field, and it has methods. 它是一个对象,它有length字段,并且有方法。 So, like any other object, it has the header, followed by the length, followed by all the array components. 因此,与任何其他对象一样,它具有标题,后跟长度,后跟所有数组组件。

An array allocated with size zero is an object that has the header and the size but no space allocated for actual components. 分配大小为零的数组是具有标题和大小但没有为实际组件分配空间的对象。

A reference to an array is just like a reference to any other object. 对数组的引用就像对任何其他对象的引用一样。 Arrays in Java are not like arrays in C, where if the array was size zero, the pointer that points to its start would actually be invalid. Java中的数组与C中的数组不同,如果数组的大小为零,则指向其开头的指针实际上是无效的。 The reference to an array points to the array object , which happens to have length zero and no actual items. 对数组的引用指向数组对象 ,该对象恰好具有零长度而没有实际项目。 If you try to address any element in such an array, there will not be a question of valid pointers. 如果您尝试解决此类数组中的任何元素,则不会出现有效指针的问题。 The array reference itself points to a valid object. 数组引用本身指向有效对象。 Then, bounds checking will show any index to be out of bounds, so no further pointer dereferencing will take place. 然后,边界检查将显示任何超出范围的索引,因此不会再进行指针解除引用。

So the bottom line is that a reference to a char[0] is a valid reference to an actual allocated object. 所以底线是对char[0]的引用是对实际分配对象的有效引用。 It simply has no data beyond the length. 它没有超出长度的数据。

And this is different than null which is a reference whose bits are all zero, thus not pointing anywhere at all. 这与null不同, null是一个参数,其位全部为零,因此根本不指向任何位置。 No memory other than the reference itself is allocated, whereas for char[0] enough memory is allocated for a header and a length. 除了引用本身之外没有分配任何内存,而对于char[0] ,为头部和长度分配了足够的内存。


As for strings, two empty strings do not necessarily point to the same character array. 至于字符串,两个空字符串不一定指向相同的字符数组。 For example, if you write: 例如,如果你写:

String a = new String();
String b = new String();

You'll get two different empty string objects. 你会得到两个不同的空字符串对象。 Each of them has a distinct empty character array that it points to. 它们中的每一个都有一个与之指向的明显的空字符数组。 This is because the no-args constructor of the String class is implemented like this: 这是因为String类的no-args构造函数实现如下:

public String() {
    this.value = new char[0];
}

You see the use of the new keyword? 你看到使用new关键字了吗? This means a new array object is allocated, not copied from anywhere. 这意味着分配了一个新的数组对象,而不是从任何地方复制。

Note, however, that if your source was: 但请注意,如果您的来源是:

String a = "";
String b = "";

Then because of interning, they would be pointing to the same string object, and thus to the same character array. 然后由于实习,它们将指向相同的字符串对象,因此指向相同的字符数组。 Also, if it was: 另外,如果它是:

String a = new String();
String b = new String(a);

Then you would have two different String objects, but they would both point to the same internal character array. 然后你会有两个不同的String对象,但它们都指向相同的内部字符数组。 This is because the constructor for the second line is: 这是因为第二行的构造函数是:

public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

Again, a pointer to an empty string is certainly not the same as a null pointer. 同样,指向空字符串的指针肯定与空指针不同。 It points to an actual string object which points to an actual character array object. 它指向一个实际的字符串对象,它指向一个实际的字符数组对象。

Two different objects created with new must be distinct with regards to reference equality, so no, they're not the same object. 使用new创建的两个不同对象在引用相等性方面必须是不同的,所以不,它们不是同一个对象。

Separately, any two Java String references to the constant string "" will refer to the same object, because compile-time constant strings get interned. 另外,对常量字符串“”的任何两个Java String引用都将引用同一个对象,因为编译时常量字符串会被实现。

Since each array object has the length property, when writing 由于每个数组对象都有length属性,因此在写入时

char a[] = new char[0];

Then the length property gets the value 0, which represents the array's size. 然后length属性获取值0,表示数组的大小。 The length field is 4 bytes, and the array has a normal header that's usually 8 bytes. length字段是4个字节,数组有一个普通的标头,通常是8个字节。

Nothing special about an empty array, it's just like any other array, but it doesn't contain elements. 关于空数组没什么特别的,它就像任何其他数组一样,但它不包含元素。

It's worth mentioning that an empty array and an array that's initialized to null are two different things. 值得一提的是,一个空数组和一个初始化为null的数组是两个不同的东西。 For example, sometimes it's just easier to return an empty array from a method instead of null . 例如,有时从方法而不是null返回空数组会更容易。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM