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

时间:2015-05-08 21:10:26

标签: java arrays string char native-code

Java原始对象被映射到本机原语 所以我的问题是如何表示char value[] = new char[0];? 它是否依赖于gcc编译器实现(本机代码)?这是否意味着所有空的Java String都指向同一个地址?

4 个答案:

答案 0 :(得分:8)

内存布局未定义,因为它是一个实现细节。

此处为{64} JVM的how IBM describes the memory layout of an array

  1. 64位用于类指针(即信令char
  2. 标志的64位(例如,说这个对象是一个数组)
  3. 锁定数据的64位(用于同步)
  4. 数组长度为64位(仅使用32位,但字段是边界对齐的)
  5. 数据为0位,因为数组没有元素
  6. 总共256位或32个字节。

    在Java中,Stringchar[]不是一回事。 String将是一个单独的对象,其中包含对char[]的引用。

答案 1 :(得分:7)

Java数组是对象。它们继承自Object类。

JVM规范没有规定对象的任何特定实现,前提是它们的行为符合规范。在实践中,它使用标题后跟对象的实际字段来实现。

Java中的数组不是只是其原始组件的序列。它是一个对象,它有length字段,并且它有方法。因此,与任何其他对象一样,它具有标题,后跟长度,后跟所有数组组件。

分配大小为零的数组是一个具有标题和大小但没有为实际组件分配空间的对象。

对数组的引用就像对任何其他对象的引用一样。 Java中的数组与C中的数组不同,如果数组的大小为零,则指向其开头的指针实际上是无效的。对数组的引用指向数组 object ,它恰好具有零长度而没有实际项目。如果您尝试解决此类数组中的任何元素,则不会出现有效指针的问题。数组引用本身指向有效对象。然后,边界检查将显示任何超出范围的索引,因此不会再进行指针解除引用。

所以底线是对char[0]的引用是对实际分配对象的有效引用。它没有超出长度的数据。

这与null不同,char[0]是一个比特全为零的引用,因此根本不指向任何地方。除了引用本身之外没有分配任何内存,而对于String a = new String(); String b = new String(); ,为头部和长度分配了足够的内存。

对于字符串,两个空字符串不一定指向相同的字符数组。例如,如果你写:

String

您将获得两个不同的空字符串对象。它们中的每一个都有一个与之指向的明显的空字符数组。这是因为public String() { this.value = new char[0]; } 类的no-args构造函数实现如下:

new

您是否看到使用String a = ""; String b = ""; 关键字?这意味着分配了一个新的数组对象,而不是从任何地方复制。

但请注意,如果您的来源是:

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

然后由于实习,它们将指向相同的字符串对象,因此指向相同的字符数组。另外,如果是:

String

然后你会有两个不同的public String(String original) { this.value = original.value; this.hash = original.hash; } 个对象,但它们都会指向相同的内部字符数组。这是因为第二行的构造函数是:

df_ts = df.resample("W", how='max')
df_ts.plot(figsize=(12,8), stacked=True)

同样,指向空字符串的指针肯定与空指针不同。它指向一个指向实际字符数组对象的实际字符串对象。

答案 2 :(得分:5)

使用new 创建的两个不同对象必须在引用相等方面是不同的,所以不,它们不是同一个对象。

另外,对常量字符串“”的任何两个Java String引用都将引用同一个对象,因为编译时常量字符串会被实现。

答案 3 :(得分:1)

由于每个数组对象都具有length属性,因此在编写

char a[] = new char[0];

然后length属性获取值0,表示数组的大小。 length字段是4个字节,数组有一个普通的标头,通常是8个字节。

空数组没什么特别之处,就像任何其他数组一样,但它不包含元素。

值得一提的是,一个空数组和一个初始化为null的数组是两个不同的东西。例如,有时从方法而不是null返回空数组会更容易。