Java:为什么Array.length没有()但是String.length()呢?

C g*_*ics 6 java

为什么当我们得到数组的长度时,我们不必放置()

int [] ar;
System.out.println(ar.length); // no parentheses 
Run Code Online (Sandbox Code Playgroud)

但对于一个字符串,它将是

String st;
System.out.println(st.length());
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 7

为什么Array.length没有()但String.length()呢?

在句法层面,它真正归结为"历史原因"和"因为那是Java(pre)1.0语言设计师决定这样做".唯一能够真正告诉你原因的是语言设计师.

然而:

  • length字段是特殊的,因为它实际上在数组对象的头中,并且获取数组的长度使用特殊的字节码.

  • 除了length危险的本机代码黑客之外,不能通过任何方式更改该字段.这样做非常重要,以避免堆损坏等问题.相比之下,甚至final可以使用反射修改普通对象.)

在这些方面,length阵列与任何其他领域完全不同.


从(pre-)Java的早期开始,在API中使用暴露字段已经过时了.

大多数人都会说这是件好事.通过在字符串,集合等上公开长度信息 length()size()方法,类库设计允许Java实现者更改相应类型的表示.如果直接暴露字段,则无法(在Java中).


dog*_*ose 6

区别在于:

  • 数组length的与实际内容无关——而是维度!数组可以有length10 个,但只包含 2 个元素。
  • 包含元素的对象(字符串是一个对象,包含多个字符)内部可能有一定数量的对象。此计数可能会有所不同,具体取决于您添加还是删除元素。所以length()方法是关于实际内容的!

原因是,数组是一种语言构造- 因此,每当您想了解有关数组的信息(长度或其他)时,您都必须从 JVM检索固定值,而不是调用计算某些内容的方法。

Array-Class 只是实际数组构造的代理。)


从技术上讲, an array(注意小a)只是array.length内存中元素的内存分配。(这就是为什么你不能简单地调整数组的大小,但在更改维度时总是需要创建一个新数组- 它需要在内存中重新定位(在 C 中称为realloc),因此有足够的空间容纳位array.length * elementSize

另一方面,列表不关心其元素在内存中的实际位置,因此允许随时动态调整大小。(因此它可以提供一个方法,size()因为它没有维度,只需要返回有关其内容的信息。)


Rog*_*gue 0

Arraylength是一个 int 字段,但 String(和其他对象)通常使用 getter 方法。

请注意,两者的区别在于字符串的“长度”只是它已存储在其内部数组中的信息量char,而数组的length字段只是其容量。

  • 这就是为什么?为什么对象没有公共字段,为什么数组不只是一个长度方法? (2认同)