1.String 字符串,使用一对""声明。
2.String实现了Serializable接口,支持序列化。实现了Comparable接口,可比较大小。
3.String内部定义了final char[] value,用于存储字符串数据,“==”用于比价两个String的地址是否相同。equals()仅用于比较两个String的内容是否相同。
?jdk中的关于String部分内容如图:
4.通过字面量的方式(不同于new方式)给字符串赋值,字符串声明在字符串常量池中。字符串常量池不会存储相同内容的字符串。
@Test
public void test() {
String s1="abc";
String s2="abc";
System.out.println(s1);
System.out.println(s2);
System.out.println(s1==s2);//true表示地址相同
}
运行结果:
?5.在常量池中的String,如果内容不同,地址自然不相同。对字符串重新赋值时,需要重写指定内存区域赋值,不能使用原有的value赋值。
@Test
public void test2() {
String s1="abc";
String s2="abc";
s1="hello";
System.out.println(s1);
System.out.println(s2);
System.out.println(s1==s2);//false,地址不相同
}
运行结果:
?6.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value.
@Test
public void test3() {
String s1="abc";
String s2="abc";
s2+="xyz";
System.out.println(s1);
System.out.println(s2);
System.out.println(s1==s2);//false,地址不相同
}
?运行结果:
?7.当使用String的replace()修改指定的字符串时,也需要重新指定内存区域赋值,不能使用原有的value.
@Test
public void test4() {
String s1="abc";
String s2=s1.replace('a', 'd');
System.out.println(s1);
System.out.println(s2);
System.out.println(s1==s2);//false,地址不相同
}
?运行结果:
?8.字面量定义,s1和s2在方法区的字符串常量池中。用构造器的方式,s3和s4在堆中的开辟空间后的地址。
@Test
public void test5() {
//字面量定义,s1和s2在方法区的字符串常量池中。
String s1="javaEE";
String s2="javaEE";
//用构造器的方式,s3和s4在堆中的开辟空间后的地址。
String s3=new String ("javaEE");
String s4=new String ("javaEE");
System.out.println(s1==s2);//true;
System.out.println(s1==s3);//false
System.out.println(s1==s4);//false
System.out.println(s3==s4);//false
}
运行结果:
定义Person类
public class Person {
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
String name;
int age;
}
?创造两个名字相同的Person类,Person类的名字用字面量的方式赋值,两个名字内容相同时,地址也相同。内容不同时,地址也不同。
@Test
public void test6() {
Person p1=new Person("Cherry",22);
Person p2=new Person("Cherry",44);
System.out.println(p1.name);
System.out.println(p2.name);
System.out.println(p1.name.equals(p2.name));//true,两个人的名字内容相同
System.out.println(p1.name==p2.name);//true,用“=”赋值,内容相同,地址也相同
System.out.println("-----------");
p1.name="Sophia";
System.out.println(p1.name);
System.out.println(p2.name);//Cherry
System.out.println(p1.name==p2.name);//false,两个name内容不同,在常量池中两个name地址一定不同不同
}
运行结果:
?9.常量和常量的拼接,结果在常量池。常量不会有相同内容的常量存在。
如果其中一个是变量,则实在堆中。
如果拼接的结果调用intern(),返回值就在常量池中。
@Test
public void test7() {
String s1="javaEE";
String s2="hadoop";
String s3="javaEEhadoop";
String s4="javaEE"+"hadoop";
String s5=s1+"hadoop";
String s6="javaEE"+s2;
String s7=s1+s2;
System.out.println(s3==s4);//true
System.out.println(s3==s5);//false
System.out.println(s3==s6);//false
System.out.println(s3==s7);//false
System.out.println(s5==s6);//false
System.out.println(s5==s7);//false
System.out.println(s6==s7);//false
String s8=s5.intern();//返回值在常量池中已经存在的值
System.out.println(s3==s8);//true
}
?运行结果:
?10.常量和常量拼接,结果在常量池。final 修饰常量,此String存储在常量池中
@Test
public void Test8() {
String s1="javaEEhadoop";
final String s2="javaEE";
String s3=s2+"hadoop";//s2不是变量,是常量,在常量池中。
System.out.println(s1==s3);//true
}
运行结果:
总之, 在常量池中,内容相同的String地址相同,内容不同,地址不同。
?如果一个String在堆中(被new出来的),一个String在常量池中,两个String的地址一定不相同
如果堆内存中有String,即用new的方式创建了2个String,则两个String的地址不同。
|