什么是字符串?就是把多个字符,串连一起。
其实是一个char[]数组
/**该值用于字符存储。*/
private final char value [];
(1)不可变字符串:String :定义好之后,就不能再去改变了(内存地址不可变,一旦修改了,就会创建一个新的内存地址)
(2)可变字符串:StringBuilder/StringBuffer :定义好之后,还可以进行修改, 改变时,不会创建新的内存地址。
String, StringBuffer, StringBuilder 都实现了 CharSequence 接口。
(1)直接赋值:String str = "myxq";
(2)通过构造器来创建:String str2 = new String("myxq");
方法区当中有一个常量池,存放常量。
(1)String str = "ABCD";
这种创建字符串方式,要么创建一个对象,要么不创建。
创建时会先到常量池当中看一下有没有存在该字符串常量。
如果已经有了,就直接使用,不会创建新的地址。(不创建对象)
如果常量池当中没有的话,就会在常量没当中创建一个对象。
(2)String str2 = new String("ABCD");
这种创建字符串方式,至少得要创建一个对象(因为使用了new,至少要在堆当中创建一个对象)
看一下,常量池当中,有没有传入的字符串常量。
如果没有,会创建一个字符串常量,放到常量池当中。
(1)表示引用为空:String str = null; 还没有初始化,没有分配内存空间。(地址为空)
(2)表示空字符串:String str = ""; 已经创建了对象,已经分配了内存。(内容为空)
比较两个字符串相不相等。
(1) == :比较两个内存地址是否相等。
(2)使用equals :它是object的方法。在object中和 == 相同,都是比较两个内存地址是否相等。
public boolean equals(Object obj) {
return (this == obj);
}
建议子类,自己去覆盖此方法,自己在内部当中去根据自己的需求来去判断两个值是否相等。
String 已经覆盖了 equals:
public boolean equals(Object anObject) {
// 1.判断传入的值是否与当前字符串地址相同,如果相同就直接返回true
if (this == anObject) {
return true;
}
// 2.如果不相等,再去判断传入的字符串是否为String类型。如果不,直接返回false
if (anObject instanceof String) {
// 是String,逐个判断每一个字符相不相等,如果全部相等返回true
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
实例:
public static void main(String[] args) {
// 在内存当中不能再去修改了,修改,就会创建新的地址
String str = "ABC";
String str2 = new String("ABC");
// 比的是对象的地址
if (str == str2) {
System.out.println("地址相等");
} else {
System.out.println("地址不相等");
}
// 因为String 覆盖了equals,比的是对象的内容
if (str.equals(str2)) {
System.out.println("内容相等");
} else {
System.out.println("内容不相等");
}
}
/* 输出结果:
* 地址不相等
* 内容相等
*/
原文:https://www.cnblogs.com/xzh0717/p/11239511.html