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是引用类型,而基本类型是值类型.意味着,如果你有:
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等)
这有几个原因,但主要归结为心理学和实施细节:
基本上,性能和实现细节,以及具有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是真还是假,机器可以弄清楚如何去做.
Ode*_*ded 10
原始类型String
是char[]
.
对于许多语言(C,Java,C#,C++等等)都是如此.