Stirng类,一个有故事的类

简介: Stirng类,一个有故事的类

一 故事背景

乐乐工作时有时候会和同事探讨一些技术问题,今天同事抛出了一个问题

String s ="str"  和 String s = new String("str")

他们有什么区别,让乐乐觉得对Stting类的了解还不够,于是准备对String类重新认识一遍

二 分析开始

简单的问题往往很复杂,乐乐觉得说的就是String,那就看看为什么他很简单,又为什么他很复杂?从源码开始扒

  1. 源码

    public final class String

      implements java.io.Serializable, Comparable, 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;
      ...
      
    这个类老长了,不过你一定看到了`final`,为啥要记这个,因为面试时会问,相加之后是几个对象。
    `String s ="str"`和 `String s = new String("str")`有没有区别,你可能说没有,但是现实是有。
    啥区别?`String s ="ss"` 是在编译时,放到常量池中的
    `String s = new String("str")` 是在运行期,做了两件事,第一放到常量池,第二放到head堆内存中,下面我们通过代码验证
    
  2. 代码验证

    String str5 = new String("杨")+new String("乐乐");
    System.out.println(str5== str5.intern() ); //true

    String str6 = new String("杨乐乐");
    System.out.println(str6== str6.intern() ); //false

    先说下面的 下面的false是因为new String的时候创建了两个对象一个对象放到了堆内存head中一个放到了常量池中,然后 执行str6.intern方法实际上是先去常量池中找是否有“杨乐乐”,如果有就返回杨乐乐,最终他们进行比较,但是str6指向的是head堆内存,而str6.intern指向的是常量池,就返回false了,然后说上面的就比较复杂,复杂在intern()这个方法。

首先 String str5 = new String("杨")+new String("乐乐");做了几件事,新建一个“杨”放在了head及常量池 又新建一个 “乐乐”放在head及常量池,
最终str5成为了new String(“杨乐乐”)的引用
而str5.intern() 实际上是 先在常量池中找“杨乐乐” ,但是他没有找到
没有找到后 “他就在常量池中增加了一个 new String(“杨乐乐”)的引用 ” 最终str6== str6.intern() 比较了两个引用相同,所以返回true。

然后我和同事说网上的答案有问题,网上的关于intern方法的解答
intern方法的用途
  关于字符串String中的intern方法,是当前的字符对象(通过new出来的对象)可以使用intern方法从常量池中获取,
如果常量池中不存在该字符串,那么就新建一个这样的字符串放到常量池中。
这里面没有说引用,同事说这个是jdk1.6和jdk1.7的区别,后来查验 的确如此。

相关文章
|
2月前
|
Java
Java 继承魔法揭秘:子类如何“一键继承”父类超能力,还能再添新技能?!
【6月更文挑战第16天】Java继承如魔法,子类`SubPower`通过`extends SuperPower`一键继承父类`SuperPower`的特性,同时还可添加新方法。继承展现代码复用的魔力,子类调用`specialAbility()`时,既展示自身能力,又能触发父类的`commonAbility()`。这种深度关联增强程序灵活性,简化复杂系统的构建,开启无限编程可能。
24 0
|
2月前
|
Java
Java 继承:当子类遇见父类,一场“继承”与“创新”的浪漫邂逅
【6月更文挑战第16天】Java继承是OOP的关键,子类继承父类的属性和方法,实现代码复用与类层次结构。例如,`Student`继承`Person`,得到`name`和`sayHello()`。继承促进创新,子类可添加新方法如`study()`。但要注意继承的适用性和复杂度,以保持代码清晰和易维护。继承让Java编程既高效又灵活。
125 57
|
2月前
|
Java
Java 继承那些事:子类悄悄“偷学”父类技能,还能“创新”独步天下!
【6月更文挑战第16天】Java中的继承允许子类“偷学”父类技能并创新。例如,`Student`继承`Person`,添加学生ID特性;`Circle`继承`Shape`,重写`draw`方法绘制圆形。继承帮助构建层次清晰的代码结构,子类可根据需求灵活创新,适应复杂业务场景,实现代码的高效与精彩。
20 3
|
3月前
|
存储 编译器 C语言
C++的面向诗篇:类的叙事与对象的旋律
C++的面向诗篇:类的叙事与对象的旋律
29 0
|
存储 安全 编译器
【巧妙继承】C++玩转继承的神级技巧
【巧妙继承】C++玩转继承的神级技巧
C++类的学习1(一)
的定义一般包括两部分,一是类的属性,二是他所拥有的方法。类的实例化是指给类的加载并初始化过程,比如一个people类,我们具体到每一个人就是类的实例化,此外一个类可以在此类上进行扩展。比如people类,我们分为 外国people 和 中国people,那么people叫做基类,外国people叫做派生类或子类
C++类的学习1(二)
的定义一般包括两部分,一是类的属性,二是他所拥有的方法。类的实例化是指给类的加载并初始化过程,比如一个people类,我们具体到每一个人就是类的实例化,此外一个类可以在此类上进行扩展。比如people类,我们分为 外国people 和 中国people,那么people叫做基类,外国people叫做派生类或子类
|
Java
2022年/一月18号善于复盘回顾内容一(java的面向对象编程中的类对象属性 方法)Java面向对象的核心继承 封装 多态。(二)
2022年/一月18号善于复盘回顾内容一(java的面向对象编程中的类对象属性 方法)Java面向对象的核心继承 封装 多态。
76 0
2022年/一月18号善于复盘回顾内容一(java的面向对象编程中的类对象属性 方法)Java面向对象的核心继承 封装 多态。(二)
|
Java
2022年/一月18号善于复盘回顾内容一(java的面向对象编程中的类对象属性 方法)Java面向对象的核心继承 封装 多态。(一)
2022年/一月18号善于复盘回顾内容一(java的面向对象编程中的类对象属性 方法)Java面向对象的核心继承 封装 多态。
79 0
2022年/一月18号善于复盘回顾内容一(java的面向对象编程中的类对象属性 方法)Java面向对象的核心继承 封装 多态。(一)