String str = new String("abc"), 这行代码究竟创建了几个 String 对象?
答案: 2个
分析:
可以将上面的代码分成 String str、 =、 "abc" 和 new String() 四部分来看待。
① String str 只是定义了一个名为 str 的 String 类型的变量, 因此它并没有创建对象;
② = 是对变量 str 进行初始化, 将某个对象的引用赋值给它, 显然也没有创建对象;
现在只剩下 new String("abc") 了. 那么, new String("abc") 为什么又能被看成 "abc" 和 new String() 呢?
我们调用了的String的构造器: public String(String original){}
常用的创建一个类的实例(对象)的方法有以下两种:
① 使用 new 创建对象;
② 调用 Class 类的 newInstance 方法, 利用反射机制创建对象.
正是使用 new 调用了 String 类的上面那个构造器方法创建了一个对象, 并将它的引用赋值给了 str 变量. 同时需要注意到, 被调用的构造器方法接收的参数也是一个 String 对象, 这个对象正是 "abc". 由此又要引入另外一种创建 String 对象的方式的讨论 —— 引号内包含文本.
这种方式是 String 特有的, 并且它与 new 的方式存在很大区别.
String str = "abc";
毫无疑问, 这行代码创建了一个String对象.
String a = "abc";
String b = "abc";
答案还是一个.
String a = "ab" + "cd";
答案是三个.
说到这里, 我们就需要引入对字符串池相关的知识.
在JAVA虚拟机(JVM)中存在着一个字符串池, 其中保存着很多 String 对象, 并且可以被共享使用, 因此它提高了效率. 由于 String 类是 final 的, 它的值一经创建就不可改变, 因此我们不用担心 String 对象共享而带来程序的混乱. 字符串池由 String 类维护, 我们可以调用 intern() 方法来访问字符串池.
只有使用引号包含文本的方式创建的 String 对象之间使用 “+” 连接产生的新对象才会被加入字符串池中. 对于所有包含 new 方式新建对象(包括 null)的 “+” 连接表达式, 它所产生的新对象都不会被加入字符串池中, 对此不再赘述. 因此提倡大家用引号包含文本的方式来创建 String 对象以提高效率, 实际上这也是在编程中常采用的.
栈(stack): 主要保存基本类型(char、byte、short、int、long、float、double、boolean)和对象的引用, 数据可以共享, 速度仅次于寄存器(register), 快于堆.
堆(heap): 用于存储对象.
String str = new String("abc"), 这行代码究竟创建了几个 String 对象?
最新推荐文章于 2024-04-20 10:02:42 发布