字符串
String : 不可变的字符序列(内容,长度,顺序)
StringBuilder : 可变的字符序列,线程不安全|不同步,效率较高
StringBuffer : 可变的字符序列,线程安全|同步的,效率较低
String :
String类表示字符串。 Java程序中的所有字符串文字(例如"abc" )都实现为此类的实例。
分析以下代码是否存在对象创建,有几个?
String str1 = "abc"; 1个 "abc" 在字符串常量池中
过程:先在常量池中寻找字符串"abc",如果没有找到,则在常量池中开辟一个空间存放"abc",并把“abc”的地址传给str1,所以str1里面指向的是“abc”的地址
String str2 = new String("bcd"); 2个 new String()->堆内存中 "bcd"->常量池中
过程:先在常量池里寻找字符串“bcd”,如果没有找到,则在常量池中开辟一个空间存放“bcd”,然后把“bcd”的地址存放在new String()在堆内存中创建的空间里,而new String()创建的空间地址传给str2,。故str2里面存放的是new String()在堆内存中的地址,new String()空间里面存放的是“bcd”在常量池中的地址
一个是字符串字面量"abc"对应的,驻留在字符串常量池的实例(类加载时创建);一个是new String("abc")在堆中创建的,内容和"abc"相同的实例(程序运行时)
"abc"字面量实例在常量池中已经存在,所以只是把先前类加载中创建好的String("abc")实例的一个引用压入操作栈顶,并没有创建String对象。
String str3 = new String("abc"); 1个 new String()->堆内存
过程:常量池中已经有了“abc”,故只创建了new的空间,指向的是“abc”的地址,str1的指向的地址和str3指向的地址是一样的。
String底层结构 :
jdk8->字符数组 private final char[] value;
jdk11->字节数组 private final byte[] value;
注意 : 以后要比较字符串内容是否相等,就使用equals方法
equals : 比较两个对象是否相等
equals与==之间的区别 :
== 能够比较任意类型数据
equals 只能比较引用数据类型对象数据
比较规则 :
== 基本数据类型比较数据值,引用数据类型对象数据比较地址值
equals :
Object-> 比较为对象的地址值,默认通过==比较
public boolean equals(Object obj) {
return (this == obj);
}
重写->根据所有属性值进行比较是否相等
注意 :
以后再定义实现类,都要根据所有属性值进行重写toString与equals
实体类规范 : javabean
1.类是公共的
2.至少 提供一个空构造,根据需求提供带参
3.私有的属性
4.公共的访问方式
5.重写toString与equals
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(str1==str3); //F
System.out.println(str1.equals(str3)); //T 被str1类重写了
故equal(str3)里面不是地址了,而是值
//疑惑解答:
staff s = new staff("哥很帅,但哥笑起来更帅",28,2021,"2020",18000.0,state1.BUSY)
当你想输出s对象的内容时,如果直接 System.out.println(s);——输出的是s对象的地址。
正确的做法应该是:调用类中的toString方法, System.out.println(s.toString())