操蛋的面试题(更新)

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内存分配:

1. 寄存器:我们在程序中无法控制
2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中
3. 堆:存放用new产生的数据
4. 静态域:存放在对象中用static定义的静态成员
5. 常量池:存放常量
6. 非RAM(随机存取存储器)存储:硬盘等永久存储空间

操蛋的面试题(更新)_第1张图片

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”。 


最烦就是这个不太理解

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常量池中的引用是不一样的

终于明白了,然并卵,面试失败

你可能感兴趣的:(操蛋的面试题(更新))