包装类是很好的,它们的目的也很清楚。但是为什么我们要省略基本类型呢?
包装类是很好的,它们的目的也很清楚。但是为什么我们要省略基本类型呢?
在 Java 中,“primitive” 通常指 “value type”。然而,C# 有一个 string
关键字,它的作用与 Java 的 String 完全相同,只是编辑器中着色方式不同。它们都是别名,指向 System.String
或 java.lang.String
类。String 在这两种语言中都不是值类型,因此在这个意义上它不是原始数据类型。
如果你认为“primitive” 意味着内置于语言中,那么 String 就是原始数据类型。只是首字母大写。字符串字面量(那些用引号括起来的东西)会自动转换为 System.String
,使用加号进行连接。所以按照这种标准,它们(和数组)就和 int、long 等一样原始。
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[](除非这是你想要的行为,或者你确实尝试减少内存使用)。string
是编译器识别的类型,它可能会有一个基于字符序列相等性的==
运算符(但是,如果将两个字符串强制转换为Object
,则==
运算符将测试引用相等性)。因此,这种设计也使得受益者受益匪浅。 - supercatString
的基本类型是 char[]
。
这适用于许多语言(如 C、Java、C#、C++ 等)。
char
是最基本的数据类型之一,而数组构造是语言的一部分。字符串实际上就是 char
数组。 - Oded字符串可以是任意长度的。Java的创始人不希望有一种原始类型,无法指定具体的内存大小。这是String在Java中不是原始类型的主要原因之一。
字符串是一种特殊情况。所有真正的原始类型(int、long等)都是按值传递,并直接在JVM中实现。字符串是引用类型,因此像任何其他类一样处理(大写字母,按引用传递...),除了编译器有特殊的钩子来处理它,就像内置类型一样(例如字符串连接符+)。
由于它已经是引用类型,所以不需要像Integer那样的包装类来将其作为类使用(例如在集合中)。
原始类型?
在Java中,字符串没有原始类型。原始类型包括int、float、double、boolean等和char。
因此,为了使用字符串,它们使用了一个对象。您实例化它,它存在于堆中,您有一个对它的引用等。
他们是如何实现的呢?将其表示值保存在char数组中。
不可变性
但他们确保了不可变性。当您有一个对String对象的引用时,您知道可以自由地将其传递给其他对象,因为该引用指向的值不会更改。所有修改字符串的方法都返回字符串的其他实例,因此不会更改其他对String的引用所表示的值。
是否可以像.NET一样采用其他方式?
可以。他们可以定义一个保留字“string”,然后编译器进行转换。
但他们没有这样做...
char[].class.getSuperclass() == Object.class
。 - user85421