String类的两种实例化方式
1.直接赋值:
String
str
= "ww";
2.构造方法:
构造方法: public String(String
str
)
,在构造里面依然要接收一个
String
类对象;
Stringstr =new String("www.YOOTK.com");
String类字符串的比较
“==”比较字符串:
public class StringDemo {
public static void main(String args[]) {
String stra = "hello"; // 直接赋值定义字符串
String strb = new String("hello"); // 构造方法定义字符串
String strc = strb; // 引用传递
System.out.println(stra == strb); // 比较结果:false
System.out.println(stra == strc); // 比较结果:false
System.out.println(strb == strc); // 比较结果:true
}
}
stra和strb值是一样的,但是结果却是false,这是因为“==”比较String对象上表示的是内存地址的比较
我们再来看看在内存中是如何比较的
可以很明显的看出地址是不一样的。
这时候就有了equals()方法,这个方法由String类提供,使用时要区分大小写
public class StringDemo {
public static void main(String args[]) {
String stra = "hello"; // 直接赋值定义字符串
String strb = new String("hello");// 构造方法定义字符串
String strc = strb; // 引用传递
System.out.println(stra.equals(strb)) ; // 比较结果:true
System.out.println(stra.equals(strc)) ; // 比较结果:true
System.out.println(strb.equals(strc)) ; // 比较结果:true
}
}
String类对象两种实例化方式的区别
1.
直接赋值
直接赋值时的堆内存自动引用
public class StringDemo {
public static void main(String args[]) {
String stra = "hello"; // 直接赋值实例化
String strb = "hello"; // 直接赋值实例化
String strc = "hello"; // 直接赋值实例化
String strd = "yootk" ; // 直接赋值实例化,内容不相同
System.out.println(stra == strb); // 判断结果:true
System.out.println(stra == strc); // 判断结果:true
System.out.println(strb == strc); // 判断结果:true
System.out.println(stra == strd); // 判断结果:false
}
}
这就有了一个问题,为什么这时候的
“==
”
生效了了呢?来看看内存分析
所有相同字符串的内存都指向到了同一块空间里面,这就引出了一个共享设计模式的概念。
共享设计模式:在JVM底层实际上存在一个对象池(不一定只保存String类),当用直接复制的方法定义了一个String类对象时,会将这个字符串使用的匿名对象入池保存,之后再有新的变量以直接赋值的方式,且内容一样,那么就不会新开辟空间,而是使用已经存在的对象分配,继续使用。
2.构造方法实例化String类对象
调用String类中的构造方法进行String类对象的实例化操作,那么一定要使用关键字new,而每当使用了使用了关键字new就表示要开辟新的堆内存空间,而这块堆内存空间的内容就是传入到构造方法中的字符串数据。
于是就有了一个方法手动将他推进坑里面
public class StringDemo {
public static void main(String args[]) {
String stra = new String("hello").intern(); // 使用构造方法定义了新的内存空间,手工入池
String strb = "hello"; // 直接赋值
System.out.println(stra == strb); // 判断结果:true
}
}
平时在使用String类时,经常会有这样的用法
public class StringDemo {
public static void main(String args[]) {
String str = "Hello "; // 直接赋值实例化String类对象
str = str + "World ";// 字符串连接,同时修改String类对象的引用关系
str += "!!!"; // 字符串连接,同时修改String类对象的引用关系
System.out.println(str);// 输出当前的String类对象内容
}
}
他在内存里面是这样执行的
他通过不停地开辟新空间和指向来改变字符串的最终内容