对java中的String的深层理解

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的地址不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值