@Test
public void test() {
String str1=new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern()==str1);

String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);
}
为什么最后输出的时候第二个是false,字符串常量池里的“java”字符串在intern()方法调用的时候为什么不是首次出现?

解决方案 »

  1.   

    目测java虚拟机启动的时候 存有java这个常量了  可能是类似 关键字 机制吧
      

  2.   

    应该是java本身的机制
      

  3.   

    百度上说可能是jvm启动的某个过程中调用了一些类似xxxstart("java")这样的方法,然后在字符串常量池里加了"java"字符串
      

  4.   

    StringBuilder添加字符时不会String一样创建新的对象,而是它内部有字符数组,通过对字符数组的操作来完成拼接,是为了节省内存。String的内部有final修饰的字符数组,所以一个字符串对象的值不可改变,拼接时新创建对象,把拼接后的值赋给新的对象。
      

  5.   

    看这里:https://blog.csdn.net/lishuangq22/article/details/80352754
      

  6.   

    程序执行到 @Test 方法之前,不知道已经加载运行了多少代码,字符串常量池里已经有很多数据是正常的。
      

  7.   

    你可以看下源码,在System.java里面的initializeSystemClass 方法中调用了Version对象的init静态方法,然后你看看Version的私有静态字符串常量有哪些就明白了。
      

  8.   

    String s1 = "Hello";
    String s2 = new String("Hello");
    String s3  = new String ("Hello").intern();这个答案是s1 = s3 ,s1 != s2
    因为字面量"Hello"是编译期就确定好的,在类被加载时候就创建的,如果类加载时该字符串在常量池中已经有了,哪这一步就忽略了,堆中的对象是在运行期才确定的,在代码new的时候创建的.在一步理解就是 对于s3 在不调用intern()时候指向的是jvm在堆中创建的那个对象的引用,就和s2一样,但是执行了intern()后,指向的是字符串常量池中的那个字符串常量,也就是s1指向的那个字符串常量的引用  虽然不知道这么说可不可以看清楚 ,如果还是有什么疑问,欢迎交流
      

  9.   

    str2.intern()==str2  为 false  因为  str2.intern() 是字符串常量池中,  而  str2 是指向堆中    引用不一样Java 字符串 之 String 赋值比较 http://www.verejava.com/?id=16993012522383
      

  10.   

           给你看一下这个测试
           String str1=new StringBuilder("计算机").append("软件").toString();
    System.out.println(str1.intern()==str1); String str2=new StringBuilder("ja").append("va").toString();
    System.out.println(str2.intern()==str2);

    String str3=new StringBuilder("计算机").append("软件").toString();
    System.out.println(str3.intern()==str3);
    System.out.println(str3.intern()==str1);