String ww ="hello world"; String ww1 = "hello"+new String(" world"); String ww2 = "hello world"; String ww3 = "hello"+" world"; System.out.println(ww.equals(ww1)); System.out.println(ww==ww1); System.out.println(ww==ww2); System.out.println(ww==ww3);
true false true true
谁能告诉我第二个为何是false??java
-------------------------------------------------------------------------------------------------------面试
华丽的分割线app
-------------------------------------------------------------------------------------------------------ui
百度了一天,我大体总结一下:spa
Java内存分配:.net
1. 寄存器:咱们在程序中没法控制
2. 栈:存放基本类型的数据和对象的引用,但对象自己不存放在栈中,而是存放在堆中
3. 堆:存放用new产生的数据
4. 静态域:存放在对象中用static定义的静态成员
5. 常量池:存放常量
6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间code
String是一个特殊的包装类数据。能够用:
对象
String ww ="hello world"; String ww1 = new String("hello world");
两种的形式来建立,第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会建立一个新的对象。
而第二种是先在栈中建立一个对String类的对象引用变量str,而后经过符号引用去字符串常量池里找有没有"hello world",若是没有,则将"hello world"存放进字符串常量池,并令str指向”hello world”,若是已经有”hello world” 则直接令str指向“hello world”。 blog
最烦就是这个不太理解内存
String ww ="hello world"; String ww1 = "hello"+new String(" world");
ww 仍是常量池中"hello world”的引用,ww1由于后半部分 new String(” world”)没法在编译期肯定,因此也是一个新建立对象”hello world””的引用,这是网上的说法
后面我找到javap -c 命令查看java真正生成的指令,目前没找到汇编代码:
java指令java指令
public static void main(java.lang.String[]); Code: 0: ldc #16 // String hello world 2: astore_1 3: new #18 // class java/lang/StringBuilder 6: dup 7: ldc #20 // String hello 9: invokespecial #22 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 12: new #25 // class java/lang/String 15: dup 16: ldc #27 // String world 18: invokespecial #29 // Method java/lang/String."<init>":(Ljava/lang/String;)V 21: invokevirtual #30 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 24: invokevirtual #34 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 27: astore_2 28: return }
ldc
将int, float或String型常量值从常量池中推送至栈顶
String ww ="hello world";
因此这个是放在常量池中的
其他的操做我YY下啊
先是从常量池中取出 "hello",而后建立一个StringBuilder,把hello做为参数放里面
StringBuilder sb = new StringBuilder("hello");
而后从常量池中取出 " world",赋值给一个String对面,
String new = new String(" world");
而后sb.append(new);
String ww1= sb.toString();
因此ww1是一个String对面的引用和ww常量池中的引用是不同的
终于明白了,然并卵,面试失败