1.String的两种实例化方式
String str="hello";//直接赋值的方式: String str=new String("hello");//实例化的方式:
两种实例化方式的比较
public class Test{ public static void main(String args[]){ String str1="hello"; String str2=new String("hello"); String str3=str2;//引用传递,str3直接指向st2的堆内存地址 String str4="hello"; //String类对象==比较,比较的是地址,而不是内容 System.out.println(str1==str2);//false System.out.println(str1==str3);//false System.out.println(str3==str2);//true System.out.println(str1==str4);//true } }
内存分析图:
构造方法实例化方式的内存图:String str = new String("hello");
字符串对象池的概念:
在字符串中,如果采用直接赋值的方式(String str="hello")进行对象的实例化,则会将匿名对象“hello”放入对象池,每当下一次对不同的对象进行直接赋值的时候会直接利 用池中原有的匿名对象,这样,所有直接赋值的String对象,如果利用相同的“hello”,则String对象==返回true;
案例:对象手工入池
public class TestDemo { public static void main(String args[]){ String str =new String("hello").intern();//对匿名对象"hello"进行手工入池操作 String str1="hello"; System.out.println(str==str1);//true } }
两种实例化方式的区别
1.直接赋值(String str = "hello"):只开辟一块堆内存空间,并且会自动入池,不会产生垃圾;
2.构造方法(String str= new String("hello");):会开辟两块堆内存空间,其中一块堆内存会变成垃圾被系统回收,而且不能够自动入池,需要通过public String intern();方法进行手工入池;
在开发的过程中不会采用构造方法进行字符串的实例化;
避免空指向
== 和·public boolean equals()比较字符串的区别;
==在对字符串比较的时候,对比的是内存地址,而equals比较的是字符串内容,在开发的过程中,equals()通过接受参数,可以避免空指向;
String str = null; if(str.equals("hello")){//此时会出现空指向异常 ... } if("hello".equals(str)){//此时equals会处理null值,可以避免空指向异常 ... }
4.String类对象一旦声明则不可以改变;而改变的只是地址,原来的字符串还是存在的,并且产生垃圾
public class TestDemo { public static void main(String args[]){ String str="hello world"; str="hello"; System.out.println(str); } }