String字符串学习之String对象认识

     String字符串是java的一种重要数据类型,从String源码中可以看出String是对char数组的一种封装和延伸,主要组成部分是char数组、offset偏移量、count长度。String的真实内容由偏移量和长度在char数组中定位和截取。

    本文章中将会讲到String的不变性和常量池

    1、String对象具有不变性,对象一旦生成就不能再改变。源码中是这样说明的:Strings are constant; their values cannot be changed after they are created。

     为什么String对象生成后就不能改变的呢?

            这个是由于(1)String类是由final关键字修饰的,这样可以保证它不可能含有子类。(2)它的所有属性也是由final修饰,确保了只能在对象被构造时被赋值一次。这也确保了不能给此属性提供setter方法。

    这样做的好处: String的不变性可以称之为不变模式(即一个对象的状态在创建后就不会再发生改变),这样做的好处保证其不可能有任何子类,对系统起到了保护作用。同时由于它的不变性可以在多线程下被共享,不需要同步机制或者锁机制,从而提高了系统性能。

  部分源码截图(jdk8)

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
 
    private final char value[];

    private int hash; // Default to 0

    private static final long serialVersionUID = -6849794470754667710L;

  
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

 2、对于字符串的常量池是String的一大特点,但是又很容易在此产生误解

      字符串的针对常量池做了一些优化,可以理解为: 只要字符串内容相同,最终都会指向同一个常量池。当一个字符串反复出现的时候,可以大大节省内存空间。

     针对下面例子详细解释:

public class StringTest {
	public static void main(String[] args){
		String str = new String("a");
		String str1 = "a";
		String str2 = "a";
		System.out.println(str==str2);
		System.out.println(str1==str2);
		System.out.println(str1==str.intern());
	}
}

结果:

 从结果看出: str1==str2 返回true  说明str1和str2引用了相同的地址,str==str2 返回false  说明了str重新开辟了内存空间。但是str1==str.intern() 返回结果为true。可见str1和str指向了同一常量池。

tip: intern() 可以返回在String对象在常量池中的引用。源码中解释:a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

咱们在分析一下常量池内容(在cmd中输入 javap -v StringTest.class)

图1:

 图2:

 

 由图2中用框圈住的可以看出,这三个变量都指向了常量池中的的#3,也就是图一用红框圈住的。

String的内存分配方式如下:

 

总之而言: 只要字符串内容相同,最终都会指向同一个常量池地址。

 

参考文章:

    1. 《Java程序性能优化  让你的Java程序更快、更稳定》. 葛一鸣

    2.  JDK8 源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值