总结 :
String类两种实例化的区别
1、直接赋值:只会开辟一块堆内存空间,并且会自动保存在对象池之中,以供下次重复使用
2、构造方法:首先会检查对象池有没有这个字符串,如果有,直接返回进行引用,不用再建立一个。所以,输出结果为true。
在实际工作中,使用直接赋值产生String类对象
- String 类表示的是字符串, 但是属于一个类,虽然可以像基本数据类型一样使用但是不是基本的数据类型
存在两种实例化方法 String = "hello" string = new string{"hello"}
直接赋值相当于一个匿名对象("hello")设置了一个名字(Str),String类的匿名对象是由系统自动生成,不在由用户自己创建,产生了匿名对象就一定在堆内存在开辟了一块堆内存空间,并且由一块栈内存指向这块堆内存
package String;
// string具有不可变性
// string 两种实例化方法区别
// string 直接赋值 不采用new的方法因为容易产生多个对象产生空间垃圾
public class StringDemo {
public static void main(String[] args) {
String str1 = "hello";
String str2 = new String("hello");
String str3 = str2;
//默认不支持 通过intent方法支持
String str4 = new String("hello").intern();
//比较的是物理地址
System.out.println(str1 == str2);
System.out.println(str4 == str1);
System.out.println(str2 == str3);
// 使用equal 比较值是否相等
System.out.println(str1.equals(str2));
System.out.println(str2.equals(str1));
System.out.println(str2.equals(str3));
}
}
第一种方法图示如下:String = "hello"
str2 str3 指向同一块内存地址
共享设计原因:
在JVM底层实际上会有一个对象池(不一定保存String对象),当代码之中使用了直接赋值的方式定义了一个String类对象时,会将此字符串对象所使用的匿名对象入池保存,而如果后续还有其他String类对象也采用直接赋值方式,并且设置了同样的内容的时候,将不会开辟新的堆内存空间,而是使用已有的对象进行引用的分配,从而继续使用。
3. 在程序中判断两个字符串是否相等 可以用string类中提供非equal()方法
通过实实例化方式完成的string类赋值 默认不支持常量池 但是可以通过intent()方法手动导入常量池
字符串常量就是string的匿名对象
第二种方法图示如下:string = new string{"hello"}
构造方法一定要用关键字new, 使用了就要开辟新的堆内存空间,若使用的构造方法的方法产生string类对象,
实际开辟的是两块堆内存空间,其中匿名对象产生内存空间将成为垃圾空间,
通过上图可可以知道 string实例化方式复制的时候会存在两个对象 其中一个string类型的匿名对象作为垃圾空间存在
4 字符串的值一旦声明不可更改 demo
public static void main(String[]args){
String str1="hello";
str1+="world";
System.out.println(str1);
}
通过内存图可见 string 不可变性
5, public String toString()
返回该对象的字符串表示 通常 tostring方法会返回一个以文本表示 此对象的字符串
//测试就是将long类型使用toString()方法输出为String类型
public class JLDtoS
{
public static void main(String[]args)
{
long a=123;
Long aa=new Long(a);//使用包装类
String ii=aa.toString();//使用aa对象的toString()方法
System.out.println(ii);//输出转换的结果
}
}
//object中的toString方法是对象才能调用的