浅谈String
话说一篇“String问题IBM面试”激起千层浪
先后出现“一场IBM面试题引发的讨论:创建String对象过程中【内存分配】的终极权威详尽解释”
“【向ZangXT等大侠提问】关于创建String新对象问题的8种情况”等等。
我又搜索了下发现很久之前的帖子“(原创)深入研究java对String字符串对象的创建以及管理”
其中主要的问题归纳起来是(后面引用时用数字代替)
1.String a = "ab";//争论是1个还是2个
2.String a = "a" + "b";//争论1个 2个 还是3个
3.String a = new String("ab");//这个基本都认为是2个
这三种情况个创立了几个对象(我这里只讨论String对象)
我们先说说1与3的区别
查阅了一下《Java程序设计与数据结构导论》里面说:
虽然字符串不是基本数据类型,但是它非常基础,也经常使用,正因为如此,Java用一对双引号来定义字符串常量。
这是一直简便的表达法。出现字符串常量时,系统自动创建一个String对象。
也就是说,对String对象,不必非得明确使用new来调用其构造方法。大多数情况下,可以使用这种简化语法。
我们看到上面红字的地方 大多数情况下效果是一样的 区别就在与使用new就要调用其构造方法
那么是不是说1和3就是一样的呢?话说尽信书不如不读书。
那我们再来看看最权威的API(1.6版)
找到String类
String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc";
等效于:
char data[] = {'a', 'b', 'c'};
String str = new String(data);
我们看到 String对象实际上就是char 数组
说明1和3都是创建了一个String对象和一个String对象引用 而1比3多创建了一个char数组
那我们再来看看2
由于API的解释 2等效于:
char data[] = {'a'};
char data1[] = {'b'};
String str = new String(data + data1);
这说明2也只创建了一个String对象和一个String对象引用 (之前创建了2个char数组)
一个字符串(例如:“hi”)仅是一个便利的写法,
它实际上是创建String对象的简写。
如果在一个方法中要多次使用字符串,
Java仅创建一个String对象来表示它。
所以,在下面代码中,两个if语句都为真
String str = "hi";
if(str == "hi")
System.out.println("真");
if(str.equals("hi"))
System.out.println("真");
第一次使用字符串"hi"时,
创建一个String对象来表示它,
引用变量str指向它的地址。
以后每次再使用这个字符串的时候,
都使用最初的那个对象。
所以1,2,3都只是创建了一个String对象而已(当然还有其他不是String的对象)