String a = new String("1"); 为什么会说这段代码会产生1个或者2个对象 我觉得你以及楼上的说的都很明白 是由于jvm对字符串的特殊处理导致 但是new这个操作必然产生一个新的对象
String a = "1"; 这段其实是把"1"这个字符串在内存中的地址给到了a
String a = new String("1"); 这段其实是以"1"这个字符串值 创建了一个新的对象 然后把这个新的对象的地址给到a
能明白不?还不明白?
那我简单写点代码注释
String a = "1"; // 由于"1"不存在与jvm中 因此创建一个新的对象来存,对象地址为 "@asd001" , 并将"1"存进去 "@asd001" = "1" 最后将该地址赋予a 因此a的地址也为"@asd001" 值是"1".
String b = new String("1"); // 由于"1"已经存在与jvm中,因此"1"的地址依旧为"@asd001", 而new String创建了一个新的对象,因此需要分配新的地址 大概"@asd002",然后这个新的地址存的其实是"1"的地址 "@asd002" = "asd001",最后把"@asd002"这个地址赋予到b这个对象上
因此你直接 a == b 比较它们的地址的得到的肯定是false
(1)只是在当前栈帧中分配了引用类型的空间,并没有值;
(2)代码前段在栈帧中分配了引用类型的空间,同时堆中分配了String实例的空间,并把实例在堆中的地址赋于栈帧中,
(3)str3第一次字面量时,分配空间创建实例abc,接着赋于str3。在定义str4字面量时,已经存在abc直接赋于str4;
(4)new String("abc");从字节码上主要有两步,一是new在堆中分配一个String类型的空间,二将"abc"字面量赋于刚刚分配的String空间上(可以查看String的构造函数,内部又是一个引用),所以虽然没有再产一个abc的内存空间,但是还是有产生一个String类型实例的空间,只是内容指向同一个。所以用==的情况str3和str4是true,str4和str5是false,从创建的实例个数在有str3的情况下执行str5是新增一个,在没有str3和str4的情况下,执行str5是两个。