Java基础之String深入解析
以下是本文目录大纲
- 生成地方和地址指向,intern()方法
- String可否被继承?
1. 生成地方和地址指向,intern()方法
先看代码
String s1 = new String("abc");
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s2);
System.out.println(s1 == s3);
System.out.println(s2 == s3);
问题:
- s1,s2,s3分别在哪?生成了几个对象?
- 结果是什么?
先看程序运行的结果
false
false
false
解析:
String s1 = new String("abc");
"abc"
会在字符串常量池里面生成一个字符串abc
new String("abc");
会在堆里面生成 abc的对象String s2 = "abc";
由于"abc"
在字符串常量池里,所以可以直接引用String s3 = new String("abc");
“abc” 先在常量池里找,找到了就不在常量池里生成了,但是
new String("abc");
会在堆里面再生成一个对象abc
画图如下:
结论:
1. 生成3个abc对象,一个在字符串常量池里,两个在堆里
2. 结果如上
扩展加强
先看代码
String s1 = new String("abc");
String s2 = "abc";
String s3 = new String("abc");
System.out.println(s1 == s1.intern());
System.out.println(s2 == s2.intern());
System.out.println(s1.intern() ==s2.intern());
备注:当使用intern()方法时,查询字符串常量池是否存在当前字符串,若不存在则将当前字符串复制到字符串常量池中,并返回字符串常量池中的引用。
问题:
- 结果是分别是什么?
解析:
s1.intern()
返回常量池里中abc对象,s1是堆对象abc,所以false
- 同理,
s2,s2.intern()
都指向字符串常量池中的对象abc,所以true
s1.intern()
和s2.intern()
都指向字符串常量池中的对象abc,所以true
画图如下:
结论:
false
true
true
2. String可否被继承?
先看代码
String s4 = "java";
String s5 = "ja";
String s6 = "va";
System.out.println(s4 == "java");
System.out.println(s4 == (s5 + s6));
System.out.println(s4 == "ja" + s6);
System.out.println((s5+s6)== "ja" + s6);
解析:
s4 == "java"
,都是常量池里的对象,返回true
(s5+s6)
会在堆里面生成 “java”,所以s4 == (s5 + s6)
返回false
- 同理
"ja" + s6
也会在堆里面生成 “java”,所以(s5+s6)== "ja" + s6
返回false
(s5+s6) == "ja" + s6
等号两边引用的对象虽然相同,但是生成的对象是不一样的,所以返回false
画图如下: