您的位置:首页 > 编程语言 > Java开发

通过六个题目简单说明java的String

2018-01-22 00:00 316 查看
@Test
public void stringDemo1(){
String a = "a1";
String b = "a" + 1;
System.out.println(a == b);// true
// 要说明一点:当两个字符串字面值连接时(相加),得到的新字符串依然是字符串字面值,保存在常量池中
}

@Test
public void stringDemo2(){
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println(a == b);// false
//  当字符串字面值与String类型变量连接时,得到的新字符串不再保存在常量池中,而是在堆中新建一个String对象来存放。很明显常量池中要求的存放的是常量,有String类型变量当然不能存在常量池中了。
}

@Test
public void stringDemo3(){
String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println(a == b);// true
// 注意此题与上一题的区别,此处是字符串字面值与String类型常量(final)连接,得到的新字符串依然保存在常量池中。
}

@Test
public void stringDemo4(){
String a = "ab";
final String bb = getBB();
String b = "a" + bb;
System.out.println(a == b);// false
/**
* 此题中第条语句:final String bb = getBB();其实与final String bb = new String(“b”);是一样的。
* 也就是说return “b”会在堆中创建一个String对象保存”b”,
* 虽然bb被定义成了final。可见并非定义为final的就保存在常量池中,
* 很明显此处bb常量引用的String对象保存在堆中,
* 因为getBB()得到的String已经保存在堆中了,
* final的String引用并不会改变String已经保存在堆中这个事实。
*/
}
private static String getBB() {
return "b";
}
private static String a5 = "ab";
@Test
public void stringDemo5(){
String s1 = "a";
String s2 = "b";
String s = s1 + s2;
System.out.println(s == a5);// false
//  当字符串字面值与String类型变量连接时,得到的新字符串不再保存在常量池中,而是在堆中新建一个String对象来存放。很明显常量池中要求的存放的是常量,有String类型变量当然不能存在常量池中了。
System.out.println(s.intern() == a5);// true
/**
* 可能很多人对intern()这个函数不了解。JDK API文档中对intern()方法的描述是:
*   返回字符串对象的规范化表示形式。
*  一个初始为空的字符串池,它由类 String 私有地维护。
*  当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
*  它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
*  所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。
*/
}

@Test
public void stringDemo6(){
String s1 = "a";
String s2 = "b";
String s = s1 + s2;
System.out.println(s == a5);// false
System.out.println(s.intern() == a5);// true
System.out.println(s.intern() == a5.intern());// true
// 这个可以不解释啦吧,Demo5都能明白,这就不是事了
}

/**
* 小试牛刀: String s = new String("xyz");创建了几个String Object? 二者之间有什么区别?
* String s = new String("xyz");
* 这个跟常量池没有关系,只要是new,都是重新分配堆空间,
* 如果不区分栈和堆,这里创建了1个String Object。
* 如果是从jvm角度来说的话,它是创建了两个对象,String s是在栈里创建了一个变量,new String("xyz")是在堆里创建了一个对象并被s引用到。
*
* 如果是String s = "xyz",那就要看常量池里有没有"xyz",如果有直接引用,如果没有则创建再引用
* 这里"xyz"本身就是pool(常量池)中的一个对象,而在运行时执行new String()时,
* 将pool中的对象复制一份放到heap中,
* 并且把heap中的这个对象的引用交给s持有。ok,
* 这条语句就创建了2个String对象。
*
*/

/**
* jdk1.8 description
* Returns a canonical representation for the string object.
* <p>
* A pool of strings, initially empty, is maintained privately by the
* class {@code String}.
* <p>
* When the intern method is invoked, if the pool already contains a
* string equal to this {@code String} object as determined by
* the {@link #equals(Object)} method, then the string from the pool is
* returned. Otherwise, this {@code String} object is added to the
* pool and a reference to this {@code String} object is returned.
* <p>
* It follows that for any two strings {@code s} and {@code t},
* {@code s.intern() == t.intern()} is {@code true}
* if and only if {@code s.equals(t)} is {@code true}.
* <p>
* All literal strings and string-valued constant expressions are
* interned. String literals are defined in section 3.10.5 of the
* <cite>The Java™ Language Specification</cite>.
*
* @return  a string that has the same contents as this string, but is
*          guaranteed to be from a pool of unique strings.
*/
public native String intern();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java String intern