Java 面试,创建了几个String 对象? 我让问!让你问!让你问!(二)

简介: Java 面试,创建了几个String 对象? 我让问!让你问!让你问!(二)

这时候玩一下池化 intrern():


image.png


加上实例看看 == 看看内存地址是不是一样:


String name1 = "JC";
String name = "JCccc";
String nameNew = new String(name1 + "ccc");
nameNew = nameNew.intern();
System.out.println(name == nameNew);


结果是 true (因为池化,nameNew 放弃了 堆的照顾,指向了字符串常量池)


image.png


这里又有个好玩的点,


就是 池化方法  intern() 的玩法,不是说调了 intern()  就 会把原先指向堆的直接指到字符串常量池。


是调了 intern()  而且 再去接收 intern() 返回的对象引用,这时候才真的会让 nameNew改变引用。


结合代码玩玩:


String name1 = "JC";
String name = "JCccc";
String nameNew = new String(name1 + "ccc");
nameNew.intern();
System.out.println(name == nameNew);
nameNew = nameNew.intern();
System.out.println(name == nameNew);


运行结果:


可以看到池化方法调用但是没有接收的时候,依然是 false ;


在池化方法调用 并接收返回,这时候nameNew才真正改变引用指向字符串常量池里的“JCccc”.


image.png


最后再放个代码例子:


//字符串常量池中的对象
String a = "JC";
//字符串常量池中的对象
String b = "ccc";
//字符串常量池中的对象
String str1 = "JC" + "ccc";
//在堆上创建的新的对象
String str2 = a + b;
//常量池中的对象
String str3 = "JCccc";
System.out.println(str1 == str2);//false    字符串常量池 的 跟 堆的 比较
System.out.println(str1 == str3);//true     字符串常量池 的 跟 字符串常量池 比较
System.out.println(str2 == str3);//false    字符串常量池 的 跟 堆的 比较
str2.intern();
System.out.println(str1 == str2);//false    str2池化不接收
System.out.println(str2 == str3);//false    str2池化不接收
str2=str2.intern();
System.out.println(str1 == str2);//true    str2池化且接收
System.out.println(str2 == str3);//true     str2池化且接收


认真看完上面我啰嗦的这些内容,


后面这些常见的  ‘这里一共创建了几个String对象 ’ 题 ,  随手拿捏。


开始整一些好玩的,也就是经常被问到的面试题:



例题1 :


这里创建了几个对象?


String name = "JCccc";
System.out.println(name);


答:


String对象一个


char[]数据一个


所以是 1个 。


咱们debug,眼看为实:


image.png


例题2:


这里创建了几个对象?


String s1 = new String("JCccc");
System.out.println();


答:


1个是字面量创建的对象,丢到了字符串常量池里面了;


1个是new String 在堆里面创建的对象。


所以是 2个。


image.png


例题3:


这里创建了几个对象?


String s = "JCccc";
String s1 = new String("JCccc");
System.out.println();


答:


也是 2个 。


1个是字面量创建的对象,丢到了字符串常量池里面了;


1个是new String 在堆里面创建的对象。


image.png


同样,debug眼见为实:


image.png


再往下走一行,看到  String s1 = new String("JCccc"); 被执行了,只加了个 String对象 :

image.png


加大难度


例题4:


这里创建了几个对象?


String s = "JCccc";
String a="JC";
String s1 = new String(a+"ccc");
System.out.println();


答:

5个


image.png


3个


image.png


再加上 new  String  和 触发StringBuilder创建  这两个  


3+2 =5


也许,很多人有疑惑,就是说即使看了了编译出来的字节码, 还是不相信 因为 + 符合 触发的 StringBuilder导致 会创建一个 String 对象。


那么我们还是眼见为实,一探到底,看一下StringBuilder的toString 源码,里面还是new了一哈:


image.png

image.png


嗯 ,这篇就到这吧。

相关文章
|
12天前
|
存储 JavaScript Java
Java 中的 String Pool 简介
本文介绍了 Java 中 String 对象及其存储机制 String Pool 的基本概念,包括字符串引用、构造方法中的内存分配、字符串文字与对象的区别、手工引用、垃圾清理、性能优化,以及 Java 9 中的压缩字符串特性。文章详细解析了 String 对象的初始化、内存使用及优化方法,帮助开发者更好地理解和使用 Java 中的字符串。
Java 中的 String Pool 简介
|
18天前
|
缓存 安全 Java
java 为什么 String 在 java 中是不可变的?
本文探讨了Java中String为何设计为不可变类型,从字符串池的高效利用、哈希码缓存、支持其他对象的安全使用、增强安全性以及线程安全等方面阐述了不可变性的优势。文中还通过具体代码示例解释了这些优点的实际应用。
java 为什么 String 在 java 中是不可变的?
|
2月前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第14天】Java零基础教学篇,手把手实践教学!
123 65
|
1月前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
44 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
12天前
|
存储 Java
Java 11 的String是如何优化存储的?
本文介绍了Java中字符串存储优化的原理和实现。通过判断字符串是否全为拉丁字符,使用`byte`代替`char`存储,以节省空间。具体实现涉及`compress`和`toBytes`方法,前者用于尝试压缩字符串,后者则按常规方式存储。代码示例展示了如何根据配置决定使用哪种存储方式。
|
1月前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
28天前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
54 7
|
1月前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
1月前
|
存储 安全 Java
美团面试:String 为什么 不可变 ?(90%答错了,尼恩来一个绝世答案)
45岁老架构师尼恩分享Java面试心得,涵盖String不可变性、字符串常量池、面试技巧等内容。尼恩强调,掌握深层技术原理,如String不可变性的真正原因,可在面试中脱颖而出,赢得高薪Offer。此外,尼恩还提供了大量技术资源和面试指导,帮助求职者提升技术水平,顺利通过大厂面试。