String、StringBuffer和StringBuilder的区别和实现原理,==与equals的区别。

String是java中用的最频繁的类之一,其内部原理是通过char[]数组实现的。其实内部char[]是定义的常量 

private final char value[];

public String() {
        this.value = "".value;
    }//默认是"";

public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }还有很多方法的重载详细看源码
。一旦定义之后不可改变,能够改变的String变量的引用地址。比如String b=new String ();指向String 创建的在堆中的对象地址,b= new String("ssss");这样b再次指向另一个在堆中的某一对象地址。而之前堆中的String对象的value是常量并没有发生改变。简而言之创建的String变量可以重新指向对象但是String的一个对象中的value数组是不能改变的这也就是为什么定义的对象无法进行末尾追加值的原因(因为你想要改变String的长度需要操作value对象而value对象呗关键字final修饰了)。

StringBuilder是可变长度的字符串长度类但是不是线程安全的而Stringbuffer 是线程安全的这是他们两者的区别(线程安全速度就慢),(详见看线程安全详解)StringBuilder也是用char[]构成的但是他可以改变对象的长度。因为内部并没有使用final关键字,在StringBuilder的append方法中对对象value值进行修改。

  ==与equals的区别

==指的是指向对象的地址是否相同。equal内部方法是把char[]的每一个值进行对比相同就返回true有一个不同就返回false。

例子:

String s1=new String("s");

String s2=new String("s");

System.out.println(s1==s2);

System.out.printlc(s1.equals(s2));

最后运行结果为false true;因为new出来对象地址不同所以不相同,而值是一样的故而得到的是false和true

String s1="s";

String s2="s";

System.out.println(s1==s2);

System.out.println(s1.equals(s2));

最后运行结果为true true这是

因为它们都是从缓冲池取出来的,由于string类比较特殊,jdk专门做了缓存优化。

  Java运行时会维护一个String Pool(String池)。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
也就是说需要看string创建的方式:

1 当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
2 Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
3 使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
4 使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

  另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

猜你喜欢

转载自blog.csdn.net/qq_35681797/article/details/82014879