从一道面试题看String宝贝

120 阅读2分钟
  • 定义一下变量
  • String str1="HelloWorld"; 
    String str2="HelloWorld";
    String str3=new String("HelloWorld") ; 
    String str4="Hello"; String str5="World"; 
    String str6="Hello"+"World"; 
    String str7=str4+str5;
    
  • 表达式输出为true的有
  • A、str1 == str2
  • B、str1 == str3
  • C、str1== str6
  • D、str1 ==str7
  • E、str1== str7.intern()
  • F、str3 == str3.intern()

首先明确一点是 "=="比较的引用类型是比较的引用地址

String是什么?

  • 进入源码看看 String操作的最终是char类型数组,但并不要误认为就是char的包装类型。char类型的包装类型为Character。
  • final 表示该属性一旦被初始化便不可改变, final 修饰的变量会在编译阶段放入到调用类的常量池中
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
​
    /** Cache the hash code for the string */
    private int hash; // Default to 0
​
    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;
  • String str1="HelloWorld";被存在常量池中 String str2="HelloWorld";再去操作时候 会先去常量池中找 如果常量池中存在,会把引用指向存在"HelloWorld"

String str3=new String("HelloWorld") 创建了几个对象

idea插件jclasslib 可以看到字节码

  • 通过jclasslib 可以看出来实例实例化一个对象
  • 【ldc】 常量池写入一个helloworld
  • 可以看出来 str1和str3是不同引用

1.png

String str7=str4+str5 发生了什么?

  • 根据我一知半解的字节码解读 这边是str4为基础创建一个对象 再append
  • 不是我们理解的去线程池中去找str2

2.png

intern()

  • str7.intern() 先去检查常量池中是否有“str7”,如果没有就将str7指向堆中的“HelloWorld”的引用存入常量池,如果有返回常量池“HelloWorld”的引用
  • 注意jdk版本

StringBuilder类

  • 是一个可变长度的数组,是对一个对象操作 使用toString方法,可以使StringBuilder对象转换为不可变的String对象

3.png

总结

  • 看到这里这题心里应该有结果 不确定 程序再跑一遍看看