String笔试面试题
Java中String类由于其特殊性(不变类),几乎是笔试面试中的必考题,当然有些题目其实没啥意思,不过关键是要通过题目掌握原理性的东西。下面六道题目,如果您全部做对了,且明白其所以然,那么Java中的关于String的笔试面试题应该难不到你了。也许您觉得polaris说的有点过了,然而彻底明白这些题目,对理解String类还是很有好处的。
写出下面各题的打印输出的结果:
1
- public static void main(String[] args) {
- String a = "a1";
- String b = "a" + 1;
- System.out.println(a == b);
- }
- public static void main(String[] args) {
- String a = "a1";
- String b = "a" + 1;
- System.out.println(a == b);
- }
2
- public static void main(String[] args) {
- String a = "ab";
- String bb = "b";
- String b = "a" + bb;
- System.out.println(a == b);
- }
- public static void main(String[] args) {
- String a = "ab";
- String bb = "b";
- String b = "a" + bb;
- System.out.println(a == b);
- }
3
- public static void main(String[] args) {
- String a = "ab";
- final String bb = "b";
- String b = "a" + bb;
- System.out.println(a == b);
- }
- public static void main(String[] args) {
- String a = "ab";
- final String bb = "b";
- String b = "a" + bb;
- System.out.println(a == b);
- }
4
- public static void main(String[] args) {
- String a = "ab";
- final String bb = getBB();
- String b = "a" + bb;
- System.out.println(a == b);
- }
- private static String getBB() {
- return "b";
- }
- public static void main(String[] args) {
- String a = "ab";
- final String bb = getBB();
- String b = "a" + bb;
- System.out.println(a == b);
- }
- private static String getBB() {
- return "b";
- }
5
- private static String a = "ab";
- public static void main(String[] args) {
- String s1 = "a";
- String s2 = "b";
- String s = s1 + s2;
- System.out.println(s == a);
- System.out.println(s.intern() == a);
- }
- private static String a = "ab";
- public static void main(String[] args) {
- String s1 = "a";
- String s2 = "b";
- String s = s1 + s2;
- System.out.println(s == a);
- System.out.println(s.intern() == a);
- }
6
- private static String a = new String("ab");
- public static void main(String[] args) {
- String s1 = "a";
- String s2 = "b";
- String s = s1 + s2;
- System.out.println(s == a);
- System.out.println(s.intern() == a);
- System.out.println(s.intern() == a.intern());
- }
- private static String a = new String("ab");
- public static void main(String[] args) {
- String s1 = "a";
- String s2 = "b";
- String s = s1 + s2;
- System.out.println(s == a);
- System.out.println(s.intern() == a);
- System.out.println(s.intern() == a.intern());
- }
(1)通过java源码分析String
我们都知道String是不可变的(immutable),不变性的体现是:String类内部通过char数组来保存字符串,而这个char数组被声明为:final。那么为什么要将String类声明为不可变呢?了解设计模式的你应该知道有一种模式叫做“不变模式”(immutable pattern),String类的设计就是使用了不变模式,有兴趣的朋友可以看看“不变模式”讲的具体是啥东东。
说完String的不可变性,需要说说String的“final性”(其实也还是不可变性决定的)。这也是有些面试官会问到的问题:我能不能写一个类继承自String?为什么?我们来看看String类的声明:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence
对于final关键字的作用不用多解释了。其实这也是“强不变模式”的一种要求(类本身声明为final或所有方法声明为final)。
(2)理解String对象的存储机制
要深入理解String必须先了解Java内存机制——运行时数据区(Runtime Data Area)。《The JavaTM Virtual Machine Specification》中将运行时数据区分为六部分(参看第三章): 1)The pc Register;2)JavaVirtual Machine Stacks;3)Heap;4)Method Area;5)Runtime Constant Pool;6)Native Method Stacks; 以上数据区的具体描述可参考规范。需要注意的是,以上只是一个规范说明,并没有规定虚拟机如何实现这些数据区。
在说明String对象存储机制之前,我们需要先了解数据区的三个部分:Java 虚拟机栈(可以简称为Java栈)、堆和运行时常量池(简称常量池)。对于Java栈和堆大家应该比较熟悉,这里有一个关键点是常量池,下面就重点介绍一下与String相关的常量池。
首先大概描述一下什么是常量池:
虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用常量的一个有序集合,包括直接常量(string,integer和floating point常量)和对其他类型、字段和方法的符号引用。池中的数据项就像数组一样是通过索引访问的。因为常量池存储了相应类型所用到的所有类型、字段和方法的符号引用,所以它在Java程序的动态链接中起着核心的作用。
<1> String相关常量池
在《The JavaTM Virtual Machine Specification》第四章有一节是专门讲解各种常量池的,其中有两个常量池是关于String的。
1)The CONSTANT_String_info Structure
对于常量池的细节此文不做过多介绍,polaris以后可能会写一序列关于Java虚拟机的文章。现在您可以查阅规范或在网上收集相关资料阅读。规范上对该常量池结构的介绍是: The CONSTANT_String_info structure is used to represent constant objects of the type String. 在该常量池结构中引用了另一个常量池结构,如2)
2)The CONSTANT_Utf8_info Structure
规范上的描述是:The CONSTANT_Utf8_info structure is used to represent constant string values.
根据上面的介绍可以看出,字符串字面值会存储在常量池中。下面来分析String对象的存储机制。
<2> String对象的存储
请看这样两个语句:
String x = "abc"; String y = new String("abcd");
现在来分析一下内存的分配情况。如图:

可以看出,x与y存在栈中,它们保存了相应对象的引用。第一条语句没有在堆中分配内存,而是将“abc”保存在常量池中。对于第二条语句,同样会在常量池中有一个“abcd”的字符串,当new时,会拷贝一份该字符串存放到堆中,于是y指向了堆中的那个“abcd”字符串。不知道polaris有没有讲明白。如果您明白了,那么做前面那六道题就没什么问题了。
3、六道题答案详解
1)true
要说明一点:当两个字符串字面值连接时(相加),得到的新字符串依然是字符串字面值,保存在常量池中。
2)false
当字符串字面值与String类型变量连接时,得到的新字符串不再保存在常量池中,而是在堆中新建一个String对象来存放。很明显常量池中要求的存放的是常量,有String类型变量当然不能存在常量池中了。
3)true
注意此题与上一题的区别,此处是字符串字面值与String类型常量连接,得到的新字符串依然保存在常量池中。
4)false
此题中第条语句:final String bb = getBB();其实与final String bb = new String(“b”);是一样的。也就是说return “b”会在堆中创建一个String对象保存”b”,虽然bb被定义成了final。可见并非定义为final的就保存在常量池中,很明显此处bb常量引用的String对象保存在堆中,因为getBB()得到的String已经保存在堆中了,final的String引用并不会改变String已经保存在堆中这个事实。
5)false,true
可能很多人对intern()这个函数不了解。JDK API文档中对intern()方法的描述是:
返回字符串对象的规范化表示形式。
一个初始为空的字符串池,它由类 String 私有地维护。
当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。
它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。
所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。
上面字符串池即为字符串常量池。明白该题结果的原因了吧。
6)false,false,true
第五题看明白后,第六题就没什么好讲的了。
String笔试面试题的更多相关文章
- 通过六个题目彻底掌握String笔试面试题
http://blog.csdn.net/chj97/article/details/6899598 1 public static void main(String[] args) { String ...
- BAT及各大互联网公司2014前端笔试面试题--JavaScript篇
很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习js更是大有裨益. 而更多的题目是我一路以来收集的,也有往年的,答案不确保一定正确, ...
- 【转】BAT及各大互联网公司2014前端笔试面试题:JavaScript篇
原文转自:http://blog.jobbole.com/78738/ 很多面试题是我自己面试BAT亲身经历碰到的.整理分享出来希望更多的前端er共同进步吧,不仅适用于求职者,对于巩固复习前端基础更是 ...
- Java笔试面试题整理第八波
转载至:http://blog.csdn.net/shakespeare001/article/details/51388516 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第六波(修正版)
转载至:http://blog.csdn.net/shakespeare001/article/details/51330745 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第五波
转载至:http://blog.csdn.net/shakespeare001/article/details/51321498 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第四波
转载至:http://blog.csdn.net/shakespeare001/article/details/51274685 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第三波
转载至:http://blog.csdn.net/shakespeare001/article/details/51247785 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
- Java笔试面试题整理第二波
转载至:http://blog.csdn.net/shakespeare001/article/details/51200163 作者:山代王(开心阳) 本系列整理Java相关的笔试面试知识点,其他几 ...
随机推荐
- C# 设计模式巩固 - 抽象工厂模式
前言 继续工厂模式高级版,抽象工厂模式.抽象工厂模式其实是从工厂方法模式拓展而来.在实际的生活中一个工厂的产品不可能是单一的,肯定是多种系列的产品. 介绍 - 抽象工厂模式 定义:(摘自百度百科~ ...
- Prism5.0开发人员指南内容(纯汉语版)
Prism指南包含以下内容: 下载并安装Prism Prism5.0新内容 介绍 初始化应用程序 组件间的依赖管理 模块化应用程序开发 实现MVVM模式 进击的MVVM 组合式用户界面 导航 松耦合组 ...
- hdu 2818 Building Block(并查集,有点点复杂)
Building Block Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- HDU 5793 A Boring Question (找规律 : 快速幂+乘法逆元)
A Boring Question Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- new/delete工作机制
body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...
- SpringAnnotation注解之@Component,@Repository,@Service,@Controller
@Component:组件,表示此写上了此注解的bean,作为一个组件存在于容器中.这样的话别的地方就可以使用@Resource这个注解来把这个组件作为一个资源来使用了.初始化bean的名字为类名首字 ...
- jmeter的三种参数化
以FTP请求(用户.密码)为例:(其他都相同) 1.文件参数化 使用配置元件中的CSV Data Set Config 配置CSV Data Set Config: 文件中存储ftp登录的用户名和密码 ...
- LINUX系统下的shell命令---grep、sed、awk
1)grep文本过滤命令 1.grep基本认识 (Global search regular expression and print out the line全局搜索研究正则表达时并显示出 ...
- 日尼玛(。・∀・)ノ゙嗨 关于使用netstat时:::*
关于使用netstat时 # netstat -tlnp | grep :22 tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1444/sshd tcp6 0 0 :::22 ...
- Python中方法的缺省参数问题分析
引言: 在Python中可以缺省给方法制定缺省值,但是这个缺省值在某些情况下确是和我们预期不太一致的-... 这个诡异的问题,曾经困然了我几天时间,才最终定位出来-.. 测试代码 from datet ...