为什么java有“String”类型而不是“string”?
包装类很好,它们的用途也很好理解。但是,为什么我们省略了基元类型呢?
包装类很好,它们的用途也很好理解。但是,为什么我们省略了基元类型呢?
Java中的“Primitive”通常意味着“值类型”。但是,C#有一个关键字,其行为与Java的String完全相同,只是编辑器以不同的方式突出显示它。它们是类 或 的别名。String 在任何一种语言中都不是值类型,因此以这种方式它不是基元。string
System.String
java.lang.String
如果“primitive”的意思是内置于语言中,那么String就是一个原语。它只使用大写字母。字符串文本(引号中的那些内容)会自动转换为 +,并且 + 用于串联。因此,通过这个令牌,它们(和数组)与整数,长头等一样原始。System.String
字符串不是包装器。String 是引用类型,而基元类型是值类型。这意味着如果您有:
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[](除非这是你想要的行为,或者你真的试图减少内存使用量)。
每个都是一个引用类型 - 这意味着你编写的所有类,框架中的每个类,甚至数组。唯一属于值类型的是简单的数值类型(int、long、short、byte、float、double、char、bool 等)。Object
这有几个原因,但它主要归结为心理学和实现细节:
基本上,性能和实现细节,以及拥有2种不同字符串类型的复杂性。其他值类型具有固定的内存占用量。一个int总是32位,一个长总是64位,一个bool总是1位,等等.2除其他外,这意味着它们可以存储在堆栈上,以便函数的所有参数都存在于一个地方。此外,到处制作巨大的琴弦副本会扼杀性能。
另请参阅:在 C# 中,为什么 String 是行为类似于值类型的引用类型?。指的是.NET,但这同样适用于Java。
1 - 在 C/C++ 和其他本机编译的语言中,这是正确的,因为它们位于进程的代码段中,操作系统通常会阻止您编辑该代码段。在Java中,这通常是不真实的,因为JVM将类文件加载到堆上,因此您可以在那里编辑字符串。但是,没有理由不能在本地编译Java程序(有工具可以做到这一点),并且某些体系结构(特别是某些版本的ARM)会直接执行Java字节码。
2 - 在实践中,其中一些类型在机器级别上具有不同的尺寸。例如,bools 在堆栈上存储为 WORD 大小(x86 上为 32 位,x64 上为 64 位)。在类/数组中,它们可能会被区别对待。这都是留给JVM的实现细节 - 规范说布尔斯要么是真的,要么是假的,机器可以弄清楚如何做到这一点。
的基元类型为 。String
char[]
对于许多语言(C,Java,C#,C++等等)都是如此。