java笔记——常量池(String pool)不可变类

不可变类:
        1.定义:创建对象后,其内容不能够被改变。 同时如果创建的是一个类,并不是类是不可变的,而是类中的属性是不可变的,被final修饰。
        在进行自定义不可变类时,首先要利用private和final进行修饰,同时需要创建进行初始化的构造函数,创建仅仅能够返回值的函数,
        2.不可变类存在的优点:能够被自由地共享、线程具有安全性、便于构造、访问、测试、使用
        3.如果以String为例子:

System.out.println("**样例1:**");
		String s1 = "123";
		String s2 = new String("123");
		if(s1==s2)
			System.out.println("1");
		else
			System.out.println("0");
		if(s1.equals(s2))
			System.out.println("11");
		else
			System.out.println("00");
		
		
		System.out.println("**样例2:**");
		String s3 = "123";
		if(s1==s3)
			System.out.println("1");
		else
			System.out.println("0");
		if(s1.equals(s3))
			System.out.println("11");
		else
			System.out.println("00");

 

通过这两个样例发现,“==”与equlas()之间存在差异,==能够判断是否为同一个对象,而equals()判断的是两个对象的值是否相等。应当进行区别的一点是,值相等并不代表对象相同。

为什么会产生这两种差距呢?

1.首先java中有两种创建String的两种方式:

第一种采用直接“字面值”赋值的方式,即:String s1="123";

第二种方式采用 “new”方式,即:String s2 = new String("123");

 

在采用第一种“字面值”赋值方法时,系统会首先到Stringpool(字符串常量池)区域中查找是否存在这样一个字符串,如果不存在,系统会在常量池中创建一个该对象"123",并将对象引用的地址返回给s1,因此s1也就指向改对象;如果已经存在对象,系统不会再浪费资源,直接将"123"地址传递给s1.

 

在这种情况下也就是  样例2  的情况,s1与s3都是字面值赋值,s1和s3中存储的都是"123"的地址,是同一个对象,因此会输出"1".

 

在采用第二种方式“new”方式时,系统会创建两个“字符串对象”,第一个在常量池中创建,第二个在堆中创建。

 

在本样例中,系统会首先到常量池中查看是否存在"123"。如果找到了,那么系统就不再在常量池中创建了,但是会在堆中创建一个"123",并且将堆中的"123"的地址返回给s2,注意这里返回的是堆中的字符串的地址。如果在常量池中未找到,首先在常量池中创建"123",再在堆中创建"123",返回堆中的地址。

 

在这种情况下也就是 样例2 的情况,s1与s2中存储的地址是不一样的,因此==返回的是"0",而equals对比的是值,值相同,则返回了"11"。

 

String pool 优缺点:保证了某字符串仅仅创建一次没节省空间与时间,但是浪费了JVM遍历常量池的时间,但总时间还是缩短的。

 

字符串常量池中的的String对象是不可变的。这样保证常量池中的对象能够被多个引用访问,但是不会改变其值。如果有引用重新进行赋值,新的值会再次存储在常量池中,作为一个新的对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值