一、intern()方法
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
String str1 = new String("123");
String str2 = "123";
String str3 = str1.intern();
System.out.println((str1 == str2) +","+ (str3 == str2));// 输出结果:false,ture
String str4 = new String("234");
String str5 = new String("234");
String str6 = str4.intern();
String str7 = str5.intern();
System.out.println((str4 == str5) +","+ (str6 == str7));// false,true
自己理解:intern相当于把new String("123");变为了 String aa = "123";
二、String a = new String();
String b = new String("");
a和b都是"",不是null
三、 //在池中和堆中分别创建String对象"abc",s1指向堆中对象
String s1 = new String("abc");
//s2直接指向池中对象"abc"
String s2 = "abc";
//在堆中新创建"abc"对象,s3指向该对象
String s3 = new String("abc");
//在池中创建对象"ab" 和 "c",并且s4指向池中对象"abc"
String s4 = "ab" + "c";
//c指向池中对象"c"
String c = "c";
//在堆中创建新的对象"abc",并且s5指向该对象
String s5 = "ab" + c;
String s6 = "ab".concat("c");
String s7 = "ab".concat(c);
System.out.println("------------实串-----------");
System.out.println(s1 == s2); //false
System.out.println(s1 == s3); //false
System.out.println(s2 == s3); //false
System.out.println(s2 == s4); //true
System.out.println(s2 == s5); //false
System.out.println(s2 == s6); //false
System.out.println(s2 == s7); //false
四、
经典题目:
String s1 = "spring";
String s2 = s1 + "summer";
s1.concat("fall");/* 产生一个字符串,但是不改变s1的值,此时 s1="spring",mm=s1.concat("fall");则mm=springfall (注意没有空格)*/
s2.concat(s1);
s1 += "winter";
System.out.println(s1 + " " + s2);
输出是什么?总共创建了几个String对象?和几个引用变量?
答案:
运行结果为:springwinter springsummer
总共创建了8个String对象:"spring", "summer" ,"springsummer" ,"fall", "springfall",
"springsummerspring ", "winter" ,"springwinter".
两个引用变量: s1 与 s2
-----------------------------------------------------------------------------------------------------------------------
随着应用程序的增长,String字面值占用大量的程序内存,对于程序而言,全部的String的字面值往往有大量的冗余。为了使java更高效的使用内存,JVM留出一块特殊的内存区域,称为"String常量池"。当编译器遇到String字面值时,它先检查该池内是否存在一个相同的String字面值。如果找到了,则将新的引用指向这个现有的String,而不是创建新的String对象。如果在String常量池没有这个String则java将在常规内存创建一个新的String对象,并且引用它,而这个String也会放入池中。
见http://deony2jacob1314.iteye.com/admin/blogs/1740022 第8。
concat方法
该方法的作用是进行字符串的连接,将两个字符串连接以后形成一个新的字符串。例如:
String s = “abc”;
String s1 = “def”;
String s2 = s.concat(s1);
则连接以后生成的新字符串s2的值是”abcdef”,而字符串s和s1的值不发生改变。如果需要连接多个字符串,可以使用如下方法:
String s = “abc”;
String s1 = “def”;
String s2 = “1234”;
String s3 = s.concat(s1).concat(s2);
则生成的新字符串s3的值为”abcdef1234”。
其实在实际使用时,语法上提供了一种更简单的形式,就是使用“+”进行字符串的连接。例如:
String s = “abc” + “1234”;
则字符串s的值是”abc1234”,这样书写更加简单直观。
而且使用“+”进行连接,不仅可以连接字符串,也可以连接其他类型。但是要求进行连接时至少有一个参与连接的内容是字符串类型。而且“+”匹配的顺序是从左向右,如果两边连接的内容都是基本数字类型则按照加法运算,如果参与连接的内容有一个是字符串才按照字符串进行连接。
例如:
int a = 10;
String s = “123” + a + 5;
则连接以后字符串s的值是“123105”,计算的过程为首先连接字符串”123”和变量a的值,生成字符串”12310”,然后使用该字符串再和数字5进行连接生成最终的结果。
而如下代码:
int a = 10;
String s = a + 5 + “123”;
则连接以后字符串s的值是”15123”,计算的过程为首先计算a和数字5,由于都是数字型则进行加法运算或者数字值15,然后再使用数字值15和字符串”123”进行连接获得最终的结果。
而下面的连接代码是错误的:
int a = 12;
String s = a + 5 + ‘s’;
因为参与连接的没有一个字符串,则计算出来的结果是数字值,在赋值时无法将一个数字值赋值给字符串s。
java中,String a = null , String a = "" 和String a 这三个之间的区别和各自适合的用法?
String a; 申明一个string类型的 a,即没有在申请内存地址,更没有在内存任何指向引用地址;
String a = null ; 申明一个string类型的 a,同时在内存里申请了一个地址,但是该地址不指向任何引用地址;
String a = "" ;申明一个string类型的 a,既在内存里申请了地址,该地址又指向一个引用该字符串的引用地址;