数组中的length和String中的length()函数的区别

9

为什么在Java中,我们谈论数组时使用length数据字段,而在谈论字符串时使用length()函数?

int a[10] = {1,2,3,4,5,6,7,8,9,10};
String str = "foo";
int a_len = a.length;
int str_len = str.length();

为什么数组中长度不是一个函数或相反的情况?

3
可能是因为数组长度被存储在数组对象的一部分中,而字符串长度不是,并且需要进行计算。 - Shmiddty
1
还在这里讨论:https://dev59.com/Tm025IYBdhLWcg3whWhm - Werner Kvalem Vesterås
1
@Shmiddty -- 这绝对是向后兼容性的问题。也许还有一些自尊心在作祟。 - Hot Licks
1
另一个问题是为什么相同的概念在其他上下文中被称为“大小”。很多不一致性。 - Hot Licks
1
@VaibhavAgarwal -- 我会归咎于早期的粗心。 - Hot Licks
显示剩余8条评论
3个回答

9

简单来说:这就是它的本来面目,一直以来都是这样。

根据JLS第10.7节的规定,数组有一个公共的final length字段。出于一致性考虑,它本应该被指定为一个方法,但实际上并没有......同样地,String也可以选择使用公共的final length字段进行实现,但实际情况并非如此。

自1.0版本以来,有一些不一致的地方一直存在——很明显,这些东西在发布后真的无法更改......


而且由于JIT很可能会内联String:length(),因此性能上也不应该有任何差异。 - cdhowie
1
是的,我确定如果重新做的话会有不同的方法。可以将数组长度作为方法调用,或者为所有对象引入只读字段的通用方案。 - Hot Licks
@jon skeet:所以,如果在后续版本中没有出现,这是否意味着他们只需向String添加长度数据字段即可? - Vaibhav Agarwal
1
@VaibhavAgarwal:这将远离通常被接受的最佳实践,即将API与实现分离。更好的解决方法应该是在数组中引入一个length()方法,但同时拥有两者可能会令人困惑,我个人认为。 - Jon Skeet
1
首先,Java很少(如果有的话)完全消除一个类或方法 - 通常它们只是“弃用”并且强烈不建议使用。其次,API的管理者(特别是主要java.类之外的API)与Java虚拟机、字节码等的管理者不同。后者通常非常保守,而前者经常过于追求新功能和选项。 - Hot Licks
显示剩余3条评论

4

String 实现了 CharSequence 接口,因此在这种情况下需要将 length 设计为方法,因为接口只能指定方法。

数组不需要实现任何接口,因此在这种情况下,length 被实现为公共的 final 字段,以避免额外的方法调用开销。

编辑:

正如 Hot Licks 在下面指出的那样,在 Java 1.4 之前并不存在 CharSequence。虽然 CharSequence 显然不是这种设计选择背后的驱动原因(因为它当时还不存在),但考虑到 String 可能需要在未来实现新的接口,这种设计仍然是有道理的。


3
当做出这个决定时,CharSequence 这个概念还不存在。 - Hot Licks
@HotLicks - 这是一个非常好的观点,这可以从1.2版String文档中得到证明。虽然CharSequence在当时不存在,但未来接口中使用length的能力很可能在决策中起了作用。我会更新我的回答。 - DaoWen
1
一个更大的问题是为什么Java没有为类似于String的对象实现一个基类并将String作为子类。CharSequence只是试图从这个疏忽中恢复过来的一个弱化尝试。 - Hot Licks

0

它被认为是一个变量而不是一个方法。这就像你创建了一个类,并且声明了 Public static int num,然后在一个方法中告诉该变量在全局范围内等于某个值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接