首先我觉得要看懂这道题还得知道inren()方法的一些知识,还要知道new String(“ab”)到底创建了几个对象。

一、intern()方法的理解(重难点)

1、intern()是字符串对象的一个方法,它底层是一个native直接是调用了本地方法

2、调用这个方法之后就是去看当前字符串是否在常量池中存在

(1)存 在:那就直接返回该字符串在字符串常量池中所对应的地址给栈中要引用这个字符串的变量。

(2)不存在:
① jdk 1.6:先在字符串常量池中创建该字符串,地址与堆中字符串地址不相同。然后再返回刚创建的字符串在字符串常量池中所对应的地址给栈中要引用这个字符串的变量。

② jdk 1.7及以后:直接将堆中(不是字符串常量池中)该字符串的地址复制到字符串常量池中,这样字符串常量池就有了该字符串的地址引用,也可以说此时字符串常量池中的字符串只是一个对 堆中字符串对象的引用,它们两个的地址相同,然后再把这个地址返回给栈中要引用这个字符串的变量。

可能你已经懵了,但是上面这句话你理解了,那么之后的intern()方法相关的面试题可以说都不在话下了,下面有一个面试题。

如果不是用双引号直接声明的String对象,可以使用String 提供的intern 方法:intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。例如:String str = new String( “I love me ?”) . intern();
jdk 1.7 分析:首先上面这个str会进栈,然后会在堆中创建一个 new String()对象,再把这个对象在堆中的地址复制给字符串常量池中,最后再将常量池中的该字符串地址引用到栈中str。

通俗点讲,intern String 就是确保字符串在内存里有一份拷贝,这样可以节约内存空间,加快字符串操作的任务的执行速度,注意,这个值会被存放在字符串内部池中。也就是 (“a” + “b” + “c”). intern() == “abc” // ture

3、对第二小点里面部分概念解释

(1)上面说到,堆中存在一个new String() 对象和字符串常量池中的字符串对象还不一样?
(2)为什么还要分jdk 1.6 和jdk 1.7及以后呢?

答:两个位置的字符串对象肯定是不一样的,我们都知道jdk 1.6时字符串常量池还在永久代(那时候叫永久代)中, 在jdk 1.7 及之后字符串常量池和静态变量就放到了堆中。堆中的字符串对象创建一般都是在eden(伊甸园)中创建的,而字符串常量池虽然也在堆中,但它们两压根就不是在一个内存区域中。对这些知识还不了解的,可以去看看我的另一些文章,里面很详细的说明了这些。

4、如何保证变量S指向的是字符串常量池中的数据呢?

方法一:String s = “hello”;//字面量定义的方式
方式二:String s = new String (“hello”).intern();
以及这种String s = new StringBuilder(“hello”).intern();

二、new String(“ab”)到底创建了几个对象?

1、执行 String str = new String(“ab”);后生成的字节码

结论:单纯执行new String(“XXX”),底层会创建两个对象。一个是在堆中创建XXX的对象,另一个是在堆中字符串常量池中创建。这两个对象的内容都是一样的,但是地址是不相同的。

2、升级:执行 String str = new String(“a”) + new String(“b”);后生成的字节码

总结:

三、intern对应的一道经典面试题

public class StringIntern {public static void main(String[] args) {String s = new String("1");//在堆中和字符串常量池中都创建了该字符串1对象,但它们地址不相同s.intern();//调用此方法之前,字符串常量池中已经存在了"1",所以什么也不做String s2 = "1";//这时在字符串常量池中已经存在1对象了,所以此步只是把new String()在常量池中创建1对象地址赋给s2System.out.println(s == s2);//jdk6:false   jdk7/8:false   一个地址是在堆中一个在常量池中肯定不相等String s3 = new String("1") + new String("1");//s3变量记录的地址为:new String("11")//执行完上一行代码以后,字符串常量池中,是否存在"11"呢?答案:不存在!!s3.intern();//在字符串常量池中生成"11"。如何理解://jdk6:创建了一个新的对象"11",也就有新的在常量池中的地址。//jdk7:此时常量中并没有创建"11",而是创建一个指向堆空间中new String("11")的地址,两个地址相同String s4 = "11";//s4变量记录的地址:使用的是上一行代码代码执行时,在常量池中生成的"11"的地址System.out.println(s3 == s4);//jdk6:false  jdk7/8:true}


再牛刀小试一哈:

那么说了这么多intern()方法也理解了它,那么这方法有什么用啊?

intern()方法的用途:在用new的方式去创建大量的字符串的时候,我们可以在其后调用intern()方法,这样在底层操作的时候,会先在堆中创建一个对象,然后在去字符串常量池中创建一个字符串对象(这是在常量池中没有该字符串的情况),由于字符串常量池中不会存在内容相同的两个字符串,都是唯一的,正式这样的原因,才会明显的降低内存的使用大小,在引用时会直接从常量池中取相应的字符串,而堆中那个在没有引用时就会被GC(垃圾回收掉)了。
像一些大型的社交网站,需要创建大量的字符串,这样的就可以使用intern ()方法了。

有用点个关注,手留余香!

一道十分经典的intern面试题(String字符串)让你彻底搞懂intern方法相关推荐

  1. string 包含_一文搞懂String常见面试题,从基础到实战,到原理分析和源码解析...

    01 string基础 1.1 Java String 类 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 1.2 创建字 ...

  2. java笔试题String字符串单词逆序how are you变成are you how

    今儿去面java,笔试上来六个编程大题也是醉了,两页纸全是英文也是棒棒哒...好多字符串方面的,其实还是挺简单的,但是有些方法感觉有点忘了......总之看面试官看我代码的表情我也是醉了.... 大概 ...

  3. Java中string字符串和char字符之间的千丝万缕

    目录 前言 String字符串和char字符的区别 拓展 相互转换 String字符串转换成char字符数组 char字符转换成String字符串 char字符数组转换成String字符串 Strin ...

  4. JavaScript强制类型转换(一)String字符串型

    JavaScript强制类型转换(一) 概念 将其他的数据类型转换作为String字符串型 方式一:调用toString()方法 方式二:调用String()函数 方式三:拼接字符串 概念 类型转换主 ...

  5. 一道经典的JavaScript面试题

    一道经典的JavaScript面试题 转载于:https://www.cnblogs.com/suoking/p/5227430.html

  6. 一道非常经典C++面试题|大厂面试

    问题1:小伙伴问我,这个unique_ptr出了作用域为什么没调它的析构函数呢? 问题2:第一个运行结果是什么?为什么? 我把问题抛到群里讨论,让大家一起思考,大家可以先思考一下: C++背景知识 C ...

  7. 解读一道微软经典面试题:海盗分宝石

    这是微软的一道经典的试题,大约是2008年左右的时候出的.这个题目虽然已经过了十多年了,但是仍然是一道非常经典的试题,值时不时拿出来看一看. 问题描述 五个海盗抢到了100颗宝石.他们决定按以下的规则 ...

  8. 一道非常棘手的 Java 面试题:i++ 是线程安全的吗

    转载自  一道非常棘手的 Java 面试题:i++ 是线程安全的吗 i++ 是线程安全的吗? 相信很多中高级的 Java 面试者都遇到过这个问题,很多对这个不是很清楚的肯定是一脸蒙逼.内心肯定还在质疑 ...

  9. 经典大数据面试题及解析

    经典大数据面试题及解析 1.下列哪个属性是hdfs-site.xml中的配置? A.dfs.replication B.fs.defaultFS C.mapreduce.framework.name ...

最新文章

  1. android联动动画,利用 CollapsingToolbarLayout 完成联动的动画效果
  2. SparkSQL 将统计结果保存到Mysql
  3. python 知识点总结
  4. Vue响应式数据: Observer模块实现
  5. 为什么会出现docker
  6. Linux学习之基本介绍
  7. Django连接现有mysql数据库
  8. CentOS7 开机自启动脚本 chkconfig方式
  9. 转行人工智能,不得不温故的数学基础知识
  10. java8 Lambda Stream collect Collectors 常用实例
  11. .net项目开发工具(V2.0)异常报告专帖
  12. javascript异步代码的回调地狱以及JQuery.deferred提供的promise解决方式
  13. 为什么visual的联机浏览功能不能用_Minecraft非正版联机教程
  14. 帆软自定义登录html,自定义登陆界面- FineReport帮助文档|报表开发|报表使用|学习教程...
  15. jvm 调优 2020.09.07
  16. svn 安装 IntelliJ IDEA 配置svn
  17. Python单例模式的多种实现方式
  18. LibVLC —— 常用函数解析
  19. 蓝桥杯真题——第39级台阶
  20. Java+spring+springmvc 基于ssm的超市进销存管理系统#毕业设计

热门文章

  1. 大数据正式京淘附加爬虫
  2. Java8新特性(一)—————Lambda表达式
  3. CAD高清全彩输出pdf文件
  4. html中显示页面布局,如何让打开的网页显示在一个页面上
  5. Input Leakage Current
  6. k8s踩坑记录——证书一年有效期
  7. MPLS:多协议标签交换
  8. linux tomcat cpu占用高,排查tomcat服务器CPU使用率过高
  9. 选好核心交换机六个关键指标有哪些?
  10. python123查找指定字符输入m_Pyton学习—字符串