在java中的长度和长度()

为什么我们有一个数组的长度作为一个属性。 array.length和String我们有一个方法str.length()

刚进入我的脑海,有什么理由吗?

首先让我们强调三种不同的方式来达到类似的目的

length数组int[]double[]String[] ) – 知道数组的长度

length()string相关的对象StringStringBuilder等) – 知道String的长度

size()集合对象ArrayListSet等) – 知道集合的大小

现在忘了length()考虑只是lengthsize()

length不是一个方法,所以完全有意义的是它不会在对象上工作。 它只适用于数组。
size()它的名字更好地描述了它,因为它是一个方法,它将用于那些使用集合的对象(集合框架),就像我在那里说的那样。

现在来length()
string不是一个原始数组(所以我们不能使用.length ),也不是一个集合(所以我们不能使用.size() ),这就是为什么我们还需要一个不同的length() (保持差异和服务目的)。

为什么回答
我觉得它很有用,容易记住,使用和友好。

简单一点,你可以把它看作是一个特殊情况的数组,而不是普通的类(有点像基元,但不是)。 string和所有的集合是类,因此获得大小,长度或类似的东西的方法。

我想在devise时的原因是性能,如果他们今天创造了它们,可能会想出类似于数组支持的集合类。

如果有人感兴趣,下面是一小段代码来说明两者在生成代码中的区别,首先来源:

 public class LengthTest { public static void main(String[] args) { int[] array = {12,1,4}; String string = "Hoo"; System.out.println(array.length); System.out.println(string.length()); } } 

切割方式不是字节代码中非常重要的部分,在类上运行javap -c会导致以下两行最后一行:

 20: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 23: aload_1 24: arraylength 25: invokevirtual #4; //Method java/io/PrintStream.println:(I)V 28: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream; 31: aload_2 32: invokevirtual #5; //Method java/lang/String.length:()I 35: invokevirtual #4; //Method java/io/PrintStream.println:(I)V 

在第一种情况下(20-25),代码只需向JVM询问数组的大小(在JNI中,这将是对GetArrayLength()的调用),而在String情况下(28-35),它需要执行方法调用来获取长度。

在90年代中期,如果没有好的JIT和东西,那么它就会导致性能完全丧失,只有java.util.Vector(或者类似的东西),而不是一个语言结构,而这个语言结构实际上不像一个类,但是速度很快。 他们当然可以把这个属性当作一个方法调用,并在编译器中进行处理,但是我认为如果对某个不是真正的类的东西有一个方法会更困惑。

.length是Java的一次性属性。 它用于查找一维数组的大小。

.length()是一种方法。 它用来查找String的长度。 它避免了重复的价值。

 int[] myArray = new int[10]; String myString = "hello world!"; List<int> myList = new ArrayList<int>(); myArray.length //gives the length of the array myString.length() //gives the length of the string myList.size() //gives the length of the list 

它很可能是在不同的时间devise了string和数组,因此最终使用了不同的约定。 一个理由是,由于string在内部使用数组,所以使用了length()方法来避免重复相同的信息。 另一个是使用length()方法有助于强调string的不变性,尽pipe数组的大小也是不可改变的。

最终,这只是一个不一致的进化,如果语言从头开始被重新devise的话,这个进化肯定会得到解决。 据我所知,没有其他语言(C#,Python,Scala等)做同样的事情,所以这可能只是作为语言的一部分的一个小小的缺陷。

无论如何,如果你使用错误的话,你会得到一个错误。 :P:D

在Java中,一个数组的长度与实际保存数据的结构分开存储。 当你创build一个数组的时候,你需要指定它的长度,这就成为了数组的一个定义属性。 不pipe你做了什么长度为N的数组(改变值,空值等),它总是一个长度为N的数组。

string的长度是附带的; 它不是string的属性,而是副产品。 虽然Javastring实际上是不可变的,但是如果可以改变它们的内容,你可以改变它们的长度。 敲掉最后一个字符(如果可能的话)会降低长度。

我知道这是一个很好的区别,我可能会被拒绝,但这是真的。 如果我创build一个长度为4的数组,那么这四个长度是数组的一个定义特征,并且不pipe内部是什么。 如果我做一个包含“狗”的string,该string是长度为4,因为它恰好包含四个字符。

我认为这是做一个具有属性和另一个方法的理由。 实际上,这可能只是一个无意的不一致,但对我来说总是有意义的,而且我总是这样想。

我被告知,对于数组而言,长度不是通过一个方法检索的,因为下面的恐惧:程序员只是在进入一个循环之前将这个长度赋值给一个局部variables(认为是一个for循环,其中的条件使用了数组的长度)应该这样做是为了减less函数调用(从而提高性能)。问题是在循环过程中长度可能会改变,而variables不会。

无论何时创build数组,都会指定其大小。 所以长度可以被认为是一个build筑属性。 对于string,它本质上是一个字符数组。 长度是char数组的一个属性。 没有必要把长度作为一个领域,因为不是所有的东西都需要这个领域。 http://www.programcreek.com/2013/11/start-from-length-length-in-java/

我只想在Fredrik的最佳答案上加一些评论。

第4.3.1节中的Java语言规范规定

一个对象是一个类实例或一个数组

所以数组在Java中的确有着非常特殊的作用。 我想知道为什么。

有人可能会争辩说,当前的实现arrays对于更好的性能是非常重要的。 但是,这是一个内部结构,不应该暴露。

他们当然可以把这个属性当作一个方法调用,并在编译器中进行处理,但是我认为如果对某个不是真正的类的东西有一个方法会更困惑。

我同意弗雷德里克的观点,一个聪明的编译器优化应该是更好的select。 这也将解决问题,即使你使用数组的属性,你还没有解决的问题,string和其他(不可变)的集合types,因为,例如, string是基于一个char数组,你可以看到String类定义:

 public final class String implements java.io.Serializable, Comparable<String>, CharSequence { private final char value[]; // ... 

我不同意它会更混乱,因为数组inheritancejava.lang.Object所有方法 。

作为一名工程师,我真的不喜欢答案:“因为它一直这样。” 希望能有更好的答案。 但在这种情况下,似乎是。

TL;博士

在我看来,这是Java的devise缺陷,不应该这样实现。