为什么java有"String"类型而不是"string"?

Rav*_*pta 16 java string reference-type primitive-types

包装类很好,它们的目的也很好理解.但为什么我们省略原始类型?

Rob*_*ser 41

这取决于你的意思"原始"

Java中的"原始"通常被认为是"价值类型".但是,C#有一个string关键字,它与Java的String完全相同,它只是被编辑器突出显示.它们是类System.String或的别名java.lang.String.String在任何一种语言中都不是值类型,因此以这种方式它不是原语.

如果用"原始"表示内置于语言中,那么String就是一个原语.它只使用大写字母.字符串文字(引号中的那些内容)自动转换为System.String和+用于连接.所以通过这个标记,它们(和数组)就像int,long等一样原始.

首先,什么是String?

String不是包装器.String是引用类型,而基本类型是值类型.意味着,如果你有:

int x = 5;
int y = x;
Run Code Online (Sandbox Code Playgroud)

x和y的内存都包含"5".但是:

String x = "a";
String y = x;
Run Code Online (Sandbox Code Playgroud)

x和y的内存都包含指向字符"a" 的指针(以及长度,偏移量,ClassInfo指针和监视器).字符串表现得像一个原语,因为它们是不可变的,所以它通常不是问题,但是如果你使用反射来改变字符串的内容(不要这样做!),x和y都会看到变化.事实上,如果你有:

char[] x = "a".toCharArray();
char[] y = x;
x[0] = 'b';
System.out.println(y[0] == 'b'); // prints "true"
Run Code Online (Sandbox Code Playgroud)

所以不要只使用char [](除非这是你想要的行为,或者你真的想减少内存使用).

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

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

这有几个原因,但主要归结为心理学和实施细节:

  • 想象一下,如果你将一个字符串传递给另一个函数并且该函数以某种方式改变了它,那么你将会遇到混乱.或者如果它将它保存在某个地方并在将来改变它会怎么样?对于大多数引用类型,您接受此作为类型的一部分,但Java开发人员认为,至少对于字符串,他们不希望用户不必担心这一点.
  • 字符串不能以原子方式处理,这意味着多线程/同步将成为一个问题.
  • 字符串文字(您在代码中放入引号中的内容)在计算机的1级可能是不可变的(出于安全原因).这可以通过在程序启动时或使用copy-on-write将它们全部复制到内存的另一部分来解决,但这很.

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

基本上,性能和实现细节,以及具有2种不同字符串类型的复杂性.其他值类型具有固定的内存占用量.int总是32位,long总是64位,bool总是1位,等等.2除此之外,这意味着它们可以存储在堆栈中,因此函数的所有参数都存在于一个地方.此外,在整个地方制作巨大的字符串副本会破坏性能.

另请参阅:在C#中,为什么String是一种行为类似值的引用类型?.指.NET,但这在Java中也适用.

1 - 在C/C++和其他本机编译语言中,这是正确的,因为它们被放置在进程的代码段中,操作系统通常会阻止您进行编辑.在Java中,这实际上通常是不真实的,因为JVM将类文件加载到堆上,因此您可以在那里编辑字符串.然而,没有理由Java程序不能被本地编译(有它做到这一点的工具),以及一些架构(ARM的主要是一些版本)直接执行Java字节码.

2 - 实际上,这些类型中的一些在机器级别上具有不同的大小.Ex bools在堆栈上以WORD大小存储(x86为32位,x64为64位).在类/数组中,它们可以被区别对待.这是一个留给JVM的实现细节 - 规范说bool是真还是假,机器可以弄清楚如何去做.

  • @Ravi - 所有对象都是引用类型(也就是所有类).唯一的Java值类型是具有关键字的那些(int,char,double等) (2认同)

Ode*_*ded 10

原始类型Stringchar[].

对于许多语言(C,Java,C#,C++等等)都是如此.

  • Oded:字符串不是char数组.String类可以使用char数组作为内部存储(并且主要是)来实现,但语言或API规范不需要这样做. (4认同)