Java中创建String、Integer、Charater直接赋值与new一个对象的区别
Java中创建String、Integer、Charater直接赋值与new一个对象的区别
String、Integer、Long、short、charater等这几个对象都是有两种声明方式,比如String可以String str = "aaa"和String str = new String("aaa");两种方式却有本质上的不同,以至于在使用中一些判断方法会弄不清楚为什么这样,最基本的比如String的"=="和".equals()"的区别,相信对刚开始学习java的朋友会难以理解,这里发表一下我的拙见,希望能帮到大家。对于JVM的内存分配我了解的也是很表面浅显,大佬们也多多指正。
Java中创建String直接赋值和new String()的区别
public class TestString {
public static void main(String[] args) {
String str1 = new String("aaa");
String str2 = new String("aaa");
String str3 = str1;
String str4 = "aaa";
String str5 = "aaa";
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str4 == str5);
System.out.println(str1 == str4);
}
}
结果为:
false
true
true
false
1、String str1 = new String("aaa"); 在栈中创建str1;在堆中new一个String对象,这里为了方便描述,记为A;"aaa"第一次出现,被丢进方法区的常量池中(是整个String对象放进常量池,而不是String的Value {'a','a','a'})。str1引用堆中的A,A用常量池中的"aaa"对象的值构造自己(可以看下图的String构造器)
2、String str2 = new String("aaa"); 过程同1,把在堆中new的String对象记为B,str2是引用的B,所以str1==str2为false
3、String str3 = str1; 在栈中创建str3,和str1都是引用堆中的A,所以str1==str3为true
4、String str4 = "aaa"; 在栈中创建str4,str4引用方法区中的"aaa"对象,所以str1==str4为false
5、String str5 = "aaa"; 在栈中创建str5,str5引用方法区中的"aaa"对象,所以str4==str5为true
详细请参考下图:
延伸至Integer、Character对象
对于Character:
Character c1 = 'a';
Character c2 = 'a';
Character c3 = new Character('a');
Character c4 = new Character('a');
System.out.println(c1 == c2);
System.out.println(c3 == c4);
结果为
true
false
分析的过程和String类似,这里就不再过多介绍
对于Integer、Long、Short:
public class TestNum{
public static void main(String[] args) {
Integer i1 = 127;
Integer i2 = 127;
Integer i3 = 128;
Integer i4 = 128;
Integer i5 = new Integer(127);
Integer i6 = new Integer(127);
Integer i7 = i5;
System.out.println(i1 == i2);
System.out.println(i3 == i4);
System.out.println(i5 == i6);
System.out.println(i1 == i6);
System.out.println(i5 == i7);
}
}
结果为:
true
false
false
false
true
这里可能会产生疑问,尤其是第二个输入为false。
这里涉及到Ingeter的自动装箱和拆箱以及缓存问题。
执行Integer i1 = 127;时,显然左边为一个对象,右边为一个int基本数据类型,这样赋值是不对的。但却能编译通过,是因为编译过程中提供了自动装箱的功能,而对于-128到127之间的自动装箱,又涉及到了Integer缓存池的内容,为了提高效率,将这区间的整数放进了Integer缓存池,在使用时,i1、i2的比较其实是当做基本数据类型来进行的,因此相等。而Integer i3 = 128;不在缓存池范围内,装箱结果是和Integer i3 = new Integer(128);完全一样的。所有是两个对象的比较,因此不相等。
上一篇: php点赞功能怎么制作
下一篇: mysql触发器怎么写