java笔记(一):String,StringBuffer,StringBuilder

xiaoxiao2021-02-27  198

主要记录java中的String赋值及比较的问题以及StringBuffer和StringBuilder

比较:==和.equals赋值:= 和 new String(“”)

比较:==和.equals

java中,除了基本数据类型(int, short, long, byte, char, boolean, float, double)存储的是值本身外,其他的数据类型存储的都是对象的引用(或者称为对象的地址)。

int a = 1, b = 1; String str1 = new String("hello"); String str2 = new String("hello"); System.out.println(a == b); //true System.out.println(str1 == str2); //false

a,b存储的都是1这个值。 而str1,str2存储的是新建的String对象的地址,两个地址不同。

//接上 System.out.println(str1.equals(str2)); //true

查看java源码中对于String的equals方法的实现:

/** 该方法覆盖了Object中的equals方法,其实不仅是String,Integer、Double等都对Object的equals方法实现了重写 */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }

赋值:= 和 new String(“”)

String str1 = "hello"; String str2 = "hello"; System.out.println(str1 == str2); //true

何故? 查阅资料,解释如下: 使用”=”为String变量赋值时,会先在字符串缓冲区查找有没有该字符串,若没有,则在字符串缓冲区新建该字符串,并将地址返回;若有,则直接将该字符串在缓冲区的地址付给变量。 使用”new String()”时,首先也会去缓冲区里边查找,不管有没有,它都会在堆里新建一个该字符串对象并返回该对象的地址,如果缓冲区里面没有,则在缓冲区里面也新建一个。

String str1 = "hello world"; String str2 = "hello"; /** "hello"+" world"在编译的过程中间就将加直接处理成了"hello world"; 而str2+" world"则被处理为new StringBuffer("hello").append(" world").toString(); */ System.out.println(str1 == "hello"+" world"); //true System.out.println(str1 == str2+" world"); //false

StringBuffer

StringBuffer和String都用来表示字符串,但两者是不同的类。 StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。 StringBuffer在实现上和String一样同样适用char[]。但在append操作时,使用System.copyarray()方法(该方法会经常出现),提高了效率。 StringBuffer是线程安全的 StringBuffer在拼接字符串时的方法: public StringBuffer append(String s)

StringBuilder

StringBuilder和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的,但速度比StringBuffer快(不能同步访问)。

String, StringBuffer, StringBuilder都不是java基本类型,而是类。 三者在存储数据事都是用char[] value. 不同之处在于String的value被final修饰过,其他两者没有。

String的内部实现

public final class String implements ... { /** The value is used for character storage. */ private final char value[];

可以看出,String内部是使用char数组来保存数据的。value值被final修饰,意味着只能初始化一次。 由此引申出关于函数字符串传参的问题。

Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用的地址。

public static void main(String[] args){ String str1 = "hello"; String str2 = "world"; change(str1, str2); System.out.println(str1+" "+str2); //输出hello world } public static void change(String str1, String str2){ str1 = str2; str2 = str1+str2; }

可能很部分人想的不一样,String也是对象,但主函数中的str1,str2却不受影响。 由上所述,函数传递的其实是对象的地址,也就是说将str1和str2两个地址传给了函数内部,无论函数内部的数据如何更改,但主程序中的变量的地址是不变的,而字符串又是不变的,只能初始化一次,因此对于传递字符串变量的函数来说,外部的字符串变量的数据是不会改的。 参考资料: http://blog.csdn.net/kingzone_2008/article/details/9220691

转载请注明原文地址: https://www.6miu.com/read-14842.html

最新回复(0)