String的面试点(”abc”与new String(“abc”)的区别)
首先是String的创建方式
String a = "abc";
String b = new String("abc");
String c = "a"+"b"+"c";
内存小知识:
堆:存放对象
栈:存放基本数据类型、引用等
常量池:String池等
数据类型:
String是对象,它的实质是一个char[]
区别在哪?
String a = “abc”;
//在常量池中查找是否已存在abc,如果没有则创建,有则返回对象地址给a
String c = “a”+”b”+”c”;
//在常量池中查找是否已存在a,如果没有则创建
//在常量池中查找是否已存在b,如果没有则创建
//在常量池中查找是否已存在c,如果没有则创建
//在常量池中查找是否已存在abc,如果没有则创建,并返回地址给c
String b = new String(“abc”);
//创建了2个对象
//对象1,在堆中创建new String(),并返回地址给b
//对象2,在常量池中查找是否已存在abc,如果没有则创建,有则返回对象地址,存储在对象1自己的内存空间里面,作为对象1的内容
可以这样粗略的说
所有new出来的,都放到堆中去
所有使用双引号的字符串,都在常量池中处理
一般人会这样说,没图说个jb啊!嗯,验证一下
关于==与equals的小说明
==:基本数据类型比较的是数值大小,引用数据类型比较的是内存地址是否一致
equals:对象的一个方法,比较的是对象在自己内存中存储的内容
验证如下:
/**
*@author iamzhuwh
*@time:2017-4-11上午9:58:38
*@desc:
*
*/
public class StringTest {
public static void main(String[] args) {
String a = "abc";
String b = new String("abc");
String c = "a"+"b"+"c";
//==的比较
System.out.println("关于==的比较-------");
System.out.println("a==b:"+(a==b));
System.out.println("a与b的地址不等,a在常量池,b在堆区,b的内容在常量池");
System.out.println("a==c:"+(a==c));
System.out.println("a与c的地址相等,a在常量池,c拼接之后的内容也在常量池,常量池是会先判断是否有相同的,没有则创建,有则直接返回地址");
System.out.println("b==c:"+(b==c));
System.out.println("b与c的地址不等,c在常量池,b在堆区,b的内容在常量池");
//equals的比较
System.out.println("\n关于equals的比较-------");
System.out.println("a.equals(b):"+a.equals(b));
System.out.println("a与b内容相等");
System.out.println("a.equals(c):"+a.equals(c));
System.out.println("a与c内容相等");
System.out.println("b.equals(c):"+b.equals(c));
System.out.println("b与c内容相等");
}
}
输出如下:
关于==的比较-------
a==b:false
a与b的地址不等,a在常量池,b在堆区,b的内容在常量池
a==c:true
a与c的地址相等,a在常量池,c拼接之后的内容也在常量池,常量池是会先判断是否有相同的,没有则创建,有则直接返回地址
b==c:false
b与c的地址不等,c在常量池,b在堆区,b的内容在常量池
关于equals的比较-------
a.equals(b):true
a与b内容相等
a.equals(c):true
a与c内容相等
b.equals(c):true
b与c内容相等
瞧瞧String源码:
String的构造方法
public String() {
this.value = new char[0];
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
瞧瞧Object里面的equals源码:
public boolean equals(Object obj) {
return (this == obj);
}
String重写了Object里面的equals方法:
public boolean equals(Object anObject) {
if (this == anObject) {//比较对象的地址是否一致
return true;
}
if (anObject instanceof String) {//判断anObject是否String的子类
String anotherString = (String) anObject;
int n = value.length;//这个是this.value
if (n == anotherString.value.length) {
//判断this与传进来的String的长度比较
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
//判断this与传进来的String的每个字符的比较
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}