长度和长度() 在 Java 中

2022-08-31 11:15:24

为什么我们将数组的长度作为属性,而对于 String,我们有一个方法?array.lengthstr.length()

有什么原因吗?


答案 1

首先,让我强调为类似目的采取的三种不同方式。

length -- 数组 (, , ) -- 知道数组的长度int[]double[]String[]

length() -- 字符串相关对象 (, 等) -- 了解字符串的长度StringStringBuilder

size() -- 集合对象 (、 等) -- 了解集合的大小ArrayListSet

现在忘记考虑只是和.length()lengthsize()

length不是一种方法,因此它完全可以理解它不会在对象上工作。它仅适用于数组。
它的名称更好地描述了它,并且由于它是一种方法,因此它将用于那些使用集合(集合框架)的对象,正如我在那里所说的那样。size()

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

作为“为什么”的答案?
我发现它很有用,易于记忆和使用,并且很友好。


答案 2

稍微简化一下,你可以把它看作是数组是一个特例,而不是普通的类(有点像基元,但不是)。String 和所有集合都是类,因此需要获取大小、长度或类似内容的方法。

我猜设计时的原因是性能。如果他们今天创建了它,他们可能会想出类似数组支持的集合类。

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

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()的调用),而在字符串情况下(28-35),它需要执行方法调用来获取长度。

在1990年代中期,如果没有好的JIT和其他东西,它只会完全扼杀性能,只有java.util.Vector(或类似的东西),而不是一个语言结构,它的行为并不像一个类,但速度很快。他们当然可以将该属性屏蔽为方法调用并在编译器中处理它,但我认为在不是真实类的东西上使用方法会更加混乱。