Java中的String类以及 == 和equals()方法的比较!

时间:2021-04-07 16:05:14

一.    实例化String对象:

1.   实例化String类的两种方式;(String首字母大写,则一看就知道它为一个类!)
前面我说了,实例化对象不止一种方法,只要能开辟一个堆内存空间,则都能为实例化成功,而使用new关键字只是其中的一种!
第一种方法:直接实例化
比如:

class StringDemo1{

public static void main(String[] args){

String name = "Nishuibaichuan";

System.out.println("姓名:" + name);

}

}

第二种方法:使用new关键字实例化

比如:

class StringDemo2{

public static void main(String[] args){

String name = new String("Nishuibaichuan");

System.out.println("姓名:" + name);

}

}


2.  两种实例化方式的区别:

(1)首先,一个字符串就是String 的匿名对象.为什么这样说啊?因为我们知道类中的方法,在另一个类中使用的话,必须的先实例化该类的对象,从而来调用该方法.用对象.方法()调用;

验证:

public class StringTest2 {

public static void main(String[] args) {

System.out.println("nishui".equals("nishui"));

}

}

运行结果:    true

由以上代码可知:一个字符串就是String 的匿名对象!

String name = "Nishuibaichuan";故这样实例化String对象,就表示将一个堆内存空间的指向传给了栈内存(name)空间.

在String类的实例化方式中,直接赋值的好处就是可以有效的节省内存空间的使用,因为赋值后的字符串,只要内容一样,他们就指向同一个堆内存空间。为什么这么说啊?因为,采用直接赋值的方式存储一个字符串后,再存储另一个相同的字符串时,他发现在这个常量池中已经有了这个字符串的存在,那么他就不在开辟另一个堆内存空间存放此字符串了,而是让此字符串指向那个和他相同的字符串存储的堆内存空间!

举例验证:

public class StringTest2 {

public static void main(String[] args) {

String str1 = "nishui";//直接定义

String str2 = "nishui";//使用new关键字定义

String str3 = "nishui";//引用传递

System.out.println("str1 == str2: " + (str1 == str2) );

System.out.println("str1 == str3: " + (str1 == str3) );

System.out.println("str2 == str3: " + (str2 == str3) );

}

}

运行结果:

str1 == str2: true

str1 == str3: true

str2 == str3: true


(2)使用new String()的方式实例化对象:

public class StringTest2 {

public static void main(String[] args) {

String str2 = new String("nishui");

}

由以上代码和以上概念可知:我们在上面曾经说过,一个字符串就是String的匿名对象,那么既然是对象那么肯定就用堆内存空间的指向啊,但是根据上面代码知道使用了new 关键字,而new关键字的作用也是开辟一个堆内存空间,那么这杨的话,岂不是重复开辟堆内存空间了?这样的话,其中开辟的一个堆内存空间就为垃圾空间,等待着java的垃圾回收机制Gc回收!

总结区别:使用直接直接赋值的方式实例化String对象, 只需要一个开辟一个堆内存空间,而使用new String()的话,则需要开辟2个堆内存空间,而其中的一个堆内存空间还会变为垃圾空间,所以,在开发中最好使用直接赋值的方式为对象开辟堆内存空间.


二:   ==  和equals()方法的比较

1.  == :他比较的是地址值是否相等;

举例:

public class StringTest1 {

public static void main(String[] args) {

String str1 = "nishui";//直接定义

String str2 = new String("nishui");//使用new关键字定义,存放在ox127中(顺便取得地址值)

String str3 = str2;//引用传递str3和str2指向同一块内存空间,都指向ox127地址

System.out.println("str1 == str2: " + (str1 == str2) );

System.out.println("str1 == str3: " + (str1 == str3) );

System.out.println("str2 == str3: " + (str2 == str3) );

}

}

运行结果:

str1 == str2: false

str1 == str3: false

str2 == str3: true

由上代码可知:String str1 = "nishui";直接定义,存放在0x123地址中(顺便取得地址值),

String str2 = new String("nishui");使用new关键字定义,存放在ox127地址中(顺便取得地址值);
String str3 = str2;//引用传递str3和str2指向同一块内存空间,都指向ox127地址;

由此可以知道 "==" 比较的是地址,因为str2和str3指向同一地址,故返回true,其余返回false;


2 .  String类中的 equals()方法:他比较的是内容是否相等;

举例:

package Nsbc.club;

public class StringTest1 {

public static void main(String[] args) {

String str1 = "nishui";//直接定义

String str2 = new String("nishui");//使用new关键字定义

String str3 = str2;//引用传递

System.out.println("str1.equals(str2): " + (str1.equals(str2)) );

System.out.println("str1.equals(str3): " + (str1.equals(str3)) );

System.out.println("str2.equals(str3): " + (str2.equals(str3)) );

}

}

运行结果:

str1.equals(str2): true

str1.equals(str3): true

str2.equals(str3): true

由此可以知道equals():他比较的是内容是否相等,因为str1,str2和str3的值相等,故返回true;

三.  字符串的内容不可改变

实际上字符串内容的改变,并不是其内容真的改变了,而是内存空间的引用关系的改变.

举例:

public class StringTest3 {

public static void main(String[] args) {

String str = "nishui";

str = str + "baichuan";//其实这并没有改变字符串的内容,这只是改变了堆内存地址的指向!

System.out.println(str);

}

}

在开发中尽量少用这样的方法,因为这样的话要断开连接2次,这样的话性能很低,如果非要使用的话,就该使用StringBuffer类,笔者会在下一篇文章中写出.