java - 为什么Java具有 “String”类型而不是 “string”?

标签 java string primitive-types reference-type

包装器类很好,它们的用途也很容易理解。但是为什么我们忽略原始类型呢?

最佳答案

这取决于您所说的“原始”

Java中的“原始”通常被认为是“值类型”。但是,C#具有string关键字,其作用与Java的String完全相同,只是编辑器以不同的方式突出显示了该关键字。它们是System.Stringjava.lang.String类的别名。字符串不是两种语言中的值类型,因此以这种方式它不是原始类型。

如果用“原始”表示语言已内置,则String是原始。它仅使用大写字母。字符串文字(用引号引起来的东西)会自动转换为System.String,并且+用于串联。因此,通过此标记,它们(和数组)与int,longs等一样原始。

首先,什么是字符串?

字符串不是包装器。字符串是引用类型,而原始类型是值类型。这意味着,如果您具有:

int x = 5;
int y = x;

x和y的内存均包含“5”。但是有:
String x = "a";
String y = x;

x和y的内存均包含指向字符“a”的指针(以及长度,偏移量,ClassInfo指针和监视器)。字符串的行为就像原始元素一样,因为它们是不可变的,因此通常不成问题,但是,例如,如果您使用反射来更改字符串的内容(不要这样做!),则x和y都会看到改变。实际上,如果您具有:
char[] x = "a".toCharArray();
char[] y = x;
x[0] = 'b';
System.out.println(y[0] == 'b'); // prints "true"

因此,不要只使用char [](除非这是您想要的行为,否则您实际上是在尝试减少内存使用)。

每个Object都是引用类型-表示您编写的所有类,框架中的每个类,甚至是数组。唯一属于数值类型的是简单的数字类型(int,long,short,byte,float,double,char,bool等)。

为什么String不像char []一样可变?

造成这种情况的原因有两个,但主要取决于心理和实现细节:
  • 想象一下,如果您将字符串传递给另一个函数,而该函数以某种方式更改了它,您会遇到的困惑情况。或者,如果将其保存在某个地方并在将来进行更改,该怎么办?对于大多数引用类型,您都将其作为类型的一部分,但是Java开发人员认为,至少对于字符串而言,他们不希望用户为此担心。
  • 不能以原子方式处理字符串,这意味着多线程/同步将成为问题。
  • 字符串文字(您在代码中加引号的内容)在计算机的level1上可能是不变的(出于安全原因)。可以通过在程序启动时将它们全部复制到内存的另一部分或使用写时复制来解决,但这很慢。

  • 为什么我们没有字符串的值类型版本?

    基本上,性能和实现的细节以及具有2种不同的字符串类型的复杂性。其他值类型具有固定的内存占用量。一个int始终为32位,一个long始终为64位,一个bool始终为1位,依此类推。2其中,这意味着它们可以存储在堆栈中,因此函数的所有参数都位于一个位置。同样,到处都是巨大的字符串副本会降低性能。

    另请参阅:In C#, why is String a reference type that behaves like a value type?。指.NET,但这在Java中同样适用。

    1-在C/C++和其他 native 编译的语言中,这是正确的,因为它们被放置在过程的代码段中,操作系统通常会阻止您对其进行编辑。在Java中,这实际上通常是不正确的,因为JVM将类文件加载到堆上,因此您可以在其中编辑字符串。但是,没有理由不能本地编译Java程序(有工具可以这样做),并且某些体系结构(尤其是某些ARM版本)可以直接执行Java字节码。

    2-实际上,其中某些类型在计算机级别具有不同的大小。 E.x. boolean 值以WORD大小存储在堆栈中(x86中为32位,x64中为64位)。在类/数组中,可以将它们区别对待。这都是JVM的实现细节-规范说bool是true还是false,机器可以弄清楚该怎么做。

    关于java - 为什么Java具有 “String”类型而不是 “string”?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2108828/

    相关文章:

    javascript - 如何在 C# 中将 Javascript 字符串写入 StringBuilder

    c# - 在 C# 中将 Excel 所有列读取为字符串

    python - 解析python中的数学表达式并求解以找到答案

    java - 为什么我们首先需要 isPrimitive() ?

    java - 将刚性 ODE 与 Java 集成

    java - 在同一个 Scala 类上定义的抽象类和最终类

    java - 我可以在 Java 中通过引用传递原始类型吗?

    java - 指针如何与 Java 中的原始类型一起使用?

    java - 无法在 ArrayList<String> 中找到匹配的字符串

    java - 当我在 Webdriver 中使用 Java 运行脚本时,我收到错误消息 "No alert is active"