为什么当我们得到数组的长度时,我们不得不放置() 像
int [] ar;
System.out.println(ar.length); // no parentheses
但对于String,它将是
String st;
System.out.println(st.length());
答案 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有一个长度方法:
String实现了CharSequence接口,它定义了一个length()方法,因此String必须具有该方法。 (定义字段不是接口的一个特性,除了静态最终常量。)字符串的长度可以是方法和一个字段,但这会分散注意力。
灵活性。 String的内部实现随着时间的推移而发生了变化:曾一度使用内部char数组和单独的 offset 和 length 字段,这些字段定义了char数组中的一个区域。这样做是为了使子串可以共享父字符串的char数组(具有不同的偏移量和长度),而不是复制数组。后来发现这种优化很少有用,所以现在,String只有一个正确大小的char数组,而length方法读取数组的长度字段。字符串不再有自己的长度字段,甚至不是私有字段,但如果它是类的公共API的一部分,它们就不能删除它,这会减少实验内部实现的灵活性。
答案 3 :(得分:0)
数组length
是一个int字段,但String(和其他对象)通常使用getter方法。
请注意,两者的区别在于字符串的“长度”只是它已存储在其内部char
数组中的信息量,但数组的length
字段是只是它的能力。