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

时间:2014-07-03 22:05:46

标签: java

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

int [] ar;
System.out.println(ar.length); // no parentheses 

但对于String,它将是

String st;
System.out.println(st.length());

4 个答案:

答案 0 :(得分:6)

  

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

在句法层面,它真正归结为“历史原因”和“因为那是Java(pre)1.0语言设计者决定这样做”。唯一可以真正告诉你为什么的人才是语言设计师。

然而:

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

  • length字段无法通过任何方式更改危险的本机代码黑客。这样做非常重要,以避免堆损坏等问题。相比之下,即使普通对象上的final也可以使用反射进行修改。)

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


自Java(早期)开始以来,在API中使用暴露字段已经过时了。

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

答案 1 :(得分:3)

区别在于:

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

原因是,数组是一个语言构造 - 因此,每当你想知道关于数组的东西时(它的长度或其他)你必须检索一个来自JVM的固定值,而不是调用评估某事的方法。

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


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

另一方面,List不关心它在存储器中的实际位置,因此可以随时动态调整大小。 (因此它可以为方法size()提供服务,因为它具有 no 维度,只需返回有关其内容的信息。)

答案 2 :(得分:1)

这是访问字段(没有括号)和调用方法之间的区别(需要括号,即使方法没有参数)。

从历史上看,除了字段之外,数组可能有方法。除了方法之外,字符串可能还有字段。字段更简单,这可能是数组使用它的原因,但至少有两个原因可以让String有一个长度方法:

  1. String实现了CharSequence接口,它定义了一个length()方法,因此String必须具有该方法。 (定义字段不是接口的一个特性,除了静态最终常量。)字符串的长度可以是方法一个字段,但这会分散注意力。

  2. 灵活性。 String的内部实现随着时间的推移而发生了变化:曾一度使用内部char数组和单独的 offset length 字段,这些字段定义了char数组中的一个区域。这样做是为了使子串可以共享父字符串的char数组(具有不同的偏移量和长度),而不是复制数组。后来发现这种优化很少有用,所以现在,String只有一个正确大小的char数组,而length方法读取数组的长度字段。字符串不再有自己的长度字段,甚至不是私有字段,但如果它是类的公共API的一部分,它们就不能删除它,这会减少实验内部实现的灵活性。

答案 3 :(得分:0)

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

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