通过六个题目彻底掌握String笔试面试题

本文通过六道典型面试题,详细解析了 Java 中 String 类的工作原理,包括字符串常量池、字符串连接行为及 intern 方法的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<div id="blog_content" class="blog_content">
    <p>    Java中String类由于其特殊性(不变类),几乎是笔试面试中的必考题,当然有些题目其实没啥意思,不过关键是要通过题目掌握原理性的东西。下面六道题目,如果您全部做对了,且明白其所以然,那么Java中的关于String的笔试面试题应该难不到你了。也许您觉得polaris说的有点过了,然而彻底明白这些题目,对理解String类还是很有好处的。</p>
<p>写出下面各题的打印输出的结果:</p>
<p><strong><span style="font-size: medium;">1</span></strong><span style="font-size: x-small;"> 
</span></p><p> <span style="font-size: x-small;"> 
</span></p><div class="dp-highlighter" id=""><div class="bar"><div class="tools">Java代码 <embed wmode="transparent" src="/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09String%20a%20%3D%20%22a1%22%3B%0A%09%09String%20b%20%3D%20%22a%22%20%2B%201%3B%0A%09%09System.out.println(a%20%3D%3D%20b)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"> <a href="javascript:void()" title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;"><img class="star" src="/images/icon_star.png" alt="收藏代码"><img class="spinner" src="/images/spinner.gif" style="display:none"></a></div></div><ol start="1" class="dp-j"><li><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) {  </span></span></li><li><span>        String a = <span class="string">"a1"</span><span>;  </span></span></li><li><span>        String b = <span class="string">"a"</span><span> + </span><span class="number">1</span><span>;  </span></span></li><li><span>        System.out.println(a == b);  </span></li><li><span>    }  </span></li></ol></div><pre class="java" name="code" codeable_id="1127799" codeable_type="Blog" source_url="http://jefferent.iteye.com/blog/1127799" pre_index="0" title="通过六个题目彻底掌握String笔试面试题" style="display: none;">public static void main(String[] args) {
		String a = "a1";
		String b = "a" + 1;
		System.out.println(a == b);
	}</pre>


<p> </p>
<p></p>


<p> </p>
<p></p>
<p> </p>
<p> </p>
<p><strong><span style="font-size: medium;">2</span></strong></p>
<p> </p>
<div class="dp-highlighter" id=""><div class="bar"><div class="tools">Java代码 <embed wmode="transparent" src="/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09String%20a%20%3D%20%22ab%22%3B%0A%09%09String%20bb%20%3D%20%22b%22%3B%0A%09%09String%20b%20%3D%20%22a%22%20%2B%20bb%3B%0A%09%09System.out.println(a%20%3D%3D%20b)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"> <a href="javascript:void()" title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;"><img class="star" src="/images/icon_star.png" alt="收藏代码"><img class="spinner" src="/images/spinner.gif" style="display:none"></a></div></div><ol start="1" class="dp-j"><li><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) {  </span></span></li><li><span>        String a = <span class="string">"ab"</span><span>;  </span></span></li><li><span>        String bb = <span class="string">"b"</span><span>;  </span></span></li><li><span>        String b = <span class="string">"a"</span><span> + bb;  </span></span></li><li><span>        System.out.println(a == b);  </span></li><li><span>    }  </span></li></ol></div><pre class="java" name="code" codeable_id="1127799" codeable_type="Blog" source_url="http://jefferent.iteye.com/blog/1127799" pre_index="1" title="通过六个题目彻底掌握String笔试面试题" style="display: none;">public static void main(String[] args) {
		String a = "ab";
		String bb = "b";
		String b = "a" + bb;
		System.out.println(a == b);
	}</pre>
<p> </p>
<p><strong><span style="font-size: medium;">3</span></strong></p>
<p> </p>
<div class="dp-highlighter" id=""><div class="bar"><div class="tools">Java代码 <embed wmode="transparent" src="/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09String%20a%20%3D%20%22ab%22%3B%0A%09%09final%20String%20bb%20%3D%20%22b%22%3B%0A%09%09String%20b%20%3D%20%22a%22%20%2B%20bb%3B%0A%09%09System.out.println(a%20%3D%3D%20b)%3B%0A%09%7D%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"> <a href="javascript:void()" title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;"><img class="star" src="/images/icon_star.png" alt="收藏代码"><img class="spinner" src="/images/spinner.gif" style="display:none"></a></div></div><ol start="1" class="dp-j"><li><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) {  </span></span></li><li><span>        String a = <span class="string">"ab"</span><span>;  </span></span></li><li><span>        <span class="keyword">final</span><span> String bb = </span><span class="string">"b"</span><span>;  </span></span></li><li><span>        String b = <span class="string">"a"</span><span> + bb;  </span></span></li><li><span>        System.out.println(a == b);  </span></li><li><span>    }  </span></li></ol></div><pre class="java" name="code" codeable_id="1127799" codeable_type="Blog" source_url="http://jefferent.iteye.com/blog/1127799" pre_index="2" title="通过六个题目彻底掌握String笔试面试题" style="display: none;">public static void main(String[] args) {
		String a = "ab";
		final String bb = "b";
		String b = "a" + bb;
		System.out.println(a == b);
	}
</pre>
<p> </p>
<p><strong><span style="font-size: medium;">4</span></strong></p>
<p> </p>
<div class="dp-highlighter" id=""><div class="bar"><div class="tools">Java代码 <embed wmode="transparent" src="/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09String%20a%20%3D%20%22ab%22%3B%0A%09%09final%20String%20bb%20%3D%20getBB()%3B%0A%09%09String%20b%20%3D%20%22a%22%20%2B%20bb%3B%0A%09%09System.out.println(a%20%3D%3D%20b)%3B%0A%09%7D%0A%0A%09private%20static%20String%20getBB()%20%7B%0A%09%09return%20%22b%22%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"> <a href="javascript:void()" title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;"><img class="star" src="/images/icon_star.png" alt="收藏代码"><img class="spinner" src="/images/spinner.gif" style="display:none"></a></div></div><ol start="1" class="dp-j"><li><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) {  </span></span></li><li><span>        String a = <span class="string">"ab"</span><span>;  </span></span></li><li><span>        <span class="keyword">final</span><span> String bb = getBB();  </span></span></li><li><span>        String b = <span class="string">"a"</span><span> + bb;  </span></span></li><li><span>        System.out.println(a == b);  </span></li><li><span>    }  </span></li><li><span>  </span></li><li><span>    <span class="keyword">private</span><span> </span><span class="keyword">static</span><span> String getBB() {  </span></span></li><li><span>        <span class="keyword">return</span><span> </span><span class="string">"b"</span><span>;  </span></span></li><li><span>    }  </span></li></ol></div><pre class="java" name="code" codeable_id="1127799" codeable_type="Blog" source_url="http://jefferent.iteye.com/blog/1127799" pre_index="3" title="通过六个题目彻底掌握String笔试面试题" style="display: none;">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";
	}</pre>
<p> </p>
<p><strong><span style="font-size: medium;">5</span></strong></p>
<p> </p>
<div class="dp-highlighter" id=""><div class="bar"><div class="tools">Java代码 <embed wmode="transparent" src="/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=%09private%20static%20String%20a%20%3D%20%22ab%22%3B%0A%0A%09public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09String%20s1%20%3D%20%22a%22%3B%0A%09%09String%20s2%20%3D%20%22b%22%3B%0A%09%09String%20s%20%3D%20s1%20%2B%20s2%3B%0A%09%09System.out.println(s%20%3D%3D%20a)%3B%0A%09%09System.out.println(s.intern()%20%3D%3D%20a)%3B%0A%09%7D" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"> <a href="javascript:void()" title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;"><img class="star" src="/images/icon_star.png" alt="收藏代码"><img class="spinner" src="/images/spinner.gif" style="display:none"></a></div></div><ol start="1" class="dp-j"><li><span><span class="keyword">private</span><span> </span><span class="keyword">static</span><span> String a = </span><span class="string">"ab"</span><span>;  </span></span></li><li><span>  </span></li><li><span><span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) {  </span></span></li><li><span>    String s1 = <span class="string">"a"</span><span>;  </span></span></li><li><span>    String s2 = <span class="string">"b"</span><span>;  </span></span></li><li><span>    String s = s1 + s2;  </span></li><li><span>    System.out.println(s == a);  </span></li><li><span>    System.out.println(s.intern() == a);  </span></li><li><span>}  </span></li></ol></div><pre class="java" name="code" codeable_id="1127799" codeable_type="Blog" source_url="http://jefferent.iteye.com/blog/1127799" pre_index="4" title="通过六个题目彻底掌握String笔试面试题" style="display: none;">	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);
	}</pre>
<p> </p>
<p><strong><span style="font-size: medium;">6</span></strong></p>
<p><strong></strong> </p>
<div class="dp-highlighter" id=""><div class="bar"><div class="tools">Java代码 <embed wmode="transparent" src="/javascripts/syntaxhighlighter/clipboard_new.swf" width="14" height="15" flashvars="clipboard=private%20static%20String%20a%20%3D%20new%20String(%22ab%22)%3B%0A%0A%09public%20static%20void%20main(String%5B%5D%20args)%20%7B%0A%09%09String%20s1%20%3D%20%22a%22%3B%0A%09%09String%20s2%20%3D%20%22b%22%3B%0A%09%09String%20s%20%3D%20s1%20%2B%20s2%3B%0A%09%09System.out.println(s%20%3D%3D%20a)%3B%0A%09%09System.out.println(s.intern()%20%3D%3D%20a)%3B%0A%09%09System.out.println(s.intern()%20%3D%3D%20a.intern())%3B%0A%09%7D%0A" quality="high" allowscriptaccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"> <a href="javascript:void()" title="收藏这段代码" onclick="code_favorites_do_favorite(this);return false;"><img class="star" src="/images/icon_star.png" alt="收藏代码"><img class="spinner" src="/images/spinner.gif" style="display:none"></a></div></div><ol start="1" class="dp-j"><li><span><span class="keyword">private</span><span> </span><span class="keyword">static</span><span> String a = </span><span class="keyword">new</span><span> String(</span><span class="string">"ab"</span><span>);  </span></span></li><li><span>  </span></li><li><span>    <span class="keyword">public</span><span> </span><span class="keyword">static</span><span> </span><span class="keyword">void</span><span> main(String[] args) {  </span></span></li><li><span>        String s1 = <span class="string">"a"</span><span>;  </span></span></li><li><span>        String s2 = <span class="string">"b"</span><span>;  </span></span></li><li><span>        String s = s1 + s2;  </span></li><li><span>        System.out.println(s == a);  </span></li><li><span>        System.out.println(s.intern() == a);  </span></li><li><span>        System.out.println(s.intern() == a.intern());  </span></li><li><span>    }  </span></li></ol></div><pre class="java" name="code" codeable_id="1127799" codeable_type="Blog" source_url="http://jefferent.iteye.com/blog/1127799" pre_index="5" title="通过六个题目彻底掌握String笔试面试题" style="display: none;">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());
	}
</pre>
<p> </p>
<p> </p>
<p><strong>(1)通过java源码分析String</strong></p>
<p>    我们都知道String是不可变的(immutable),不变性的体现是:String类内部通过char数组来保存字符串,而这个char数组被声明为:final。那么为什么要将String类声明为不可变呢?了解设计模式的你应该知道有一种模式叫做“不变模式”(immutable pattern),String类的设计就是使用了不变模式,有兴趣的朋友可以看看“不变模式”讲的具体是啥东东。</p>
<p>    说完String的不可变性,需要说说String的“final性”(其实也还是不可变性决定的)。这也是有些面试官会问到的问题:我能不能写一个类继承自String?为什么?我们来看看String类的声明:</p>
<p>public final class String implements java.io.Serializable, Comparable<String>, CharSequence</p>
<p> </p>
<p> </p>
<p> </p>
<pre></pre>
<p> </p>
<p>    对于final关键字的作用不用多解释了。其实这也是“强不变模式”的一种要求(类本身声明为final或所有方法声明为final)。</p>
<p><strong>(2)理解String对象的存储机制</strong></p>
<p>    要深入理解String必须先了解Java内存机制——运行时数据区(Runtime Data Area)。《The JavaTM Virtual Machine Specification》中将运行时数据区分为六部分(参看第三章):<br>1)The pc Register;2)Java Virtual Machine Stacks;3)Heap;4)Method Area;5)Runtime Constant Pool;6)Native Method Stacks;<br>    以上数据区的具体描述可参考规范。需要注意的是,以上只是一个规范说明,并没有规定虚拟机如何实现这些数据区。</p>
<p>在说明String对象存储机制之前,我们需要先了解数据区的三个部分:Java 虚拟机栈(可以简称为Java栈)、堆和运行时常量池(简称常量池)。对于Java栈和堆大家应该比较熟悉,这里有一个关键点是常量池,下面就重点介绍一下与String相关的常量池。</p>
<p>    首先大概描述一下什么是常量池:</p>
<p> </p>
<p><em><span style="background-color: #ffffff;">虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用常量的一个有序集合,包括直接常量(string,integer和floating point常量)和对其他类型、字段和方法的符号引用。池中的数据项就像数组一样是通过索引访问的。因为常量池存储了相应类型所用到的所有类型、字段和方法的符号引用,所以它在Java程序的动态链接中起着核心的作用。</span></em></p>
<p><em></em></p>
<p><strong><1> String相关常量池</strong></p>
<p>    在《The JavaTM Virtual Machine Specification》第四章有一节是专门讲解各种常量池的,其中有两个常量池是关于String的。</p>
<p>    1)The CONSTANT_String_info Structure</p>
<p>    对于常量池的细节此文不做过多介绍,polaris以后可能会写一序列关于Java虚拟机的文章。现在您可以查阅规范或在网上收集相关资料阅读。规范上对该常量池结构的介绍是:<br>The CONSTANT_String_info structure is used to represent constant objects of the type String.<br>在该常量池结构中引用了另一个常量池结构,如2)</p>
<p>    2)The CONSTANT_Utf8_info Structure</p>
<p>    规范上的描述是:The CONSTANT_Utf8_info structure is used to represent constant string values.</p>
<p>根据上面的介绍可以看出,字符串字面值会存储在常量池中。下面来分析String对象的存储机制。</p>
<p><strong><2> String对象的存储</strong></p>
<p>    请看这样两个语句:</p>
<p>String x = "abc"; String y = new String("abcd");</p>
<p> </p>
<p> </p>
<p> </p>
<pre></pre>
<p> 现在来分析一下内存的分配情况。如图:</p>
<p style="text-align: center;"><img height="208" width="257" src="http://dl.iteye.com/upload/picture/pic/94590/b55a6e68-89be-3c2f-ad0a-e28f101e7118.jpg" alt=""></p>
<p style="text-align: left;">    可以看出,x与y存在栈中,它们保存了相应对象的引用。第一条语句没有在堆中分配内存,而是将“abc”保存在常量池中。对于第二条语句,同样会在常量池中有一个“abcd”的字符串,当new时,会拷贝一份该字符串存放到堆中,于是y指向了堆中的那个“abcd”字符串。不知道polaris有没有讲明白。如果您明白了,那么做前面那六道题就没什么问题了。</p>
<p style="text-align: left;"> </p>
<p style="text-align: left;"><strong>3、六道题答案详解</strong></p>
<p>1)true</p>
<p>    要说明一点:当两个字符串字面值连接时(相加),得到的新字符串依然是字符串字面值,保存在常量池中。</p>
<p>2)false</p>
<p>    当字符串字面值与String类型变量连接时,得到的新字符串不再保存在常量池中,而是在堆中新建一个String对象来存放。很明显常量池中要求的存放的是常量,有String类型变量当然不能存在常量池中了。</p>
<p> 3)true</p>
<p>    注意此题与上一题的区别,此处是字符串字面值与String类型常量连接,得到的新字符串依然保存在常量池中。</p>
<p>4)false</p>
<p>    此题中第条语句:final String bb = getBB();其实与final String bb = new String(“b”);是一样的。也就是说return “b”会在堆中创建一个String对象保存”b”,虽然bb被定义成了final。可见并非定义为final的就保存在常量池中,很明显此处bb常量引用的String对象保存在堆中,因为getBB()得到的String已经保存在堆中了,final的String引用并不会改变String已经保存在堆中这个事实。</p>
<p>5)false,true</p>
<p>    可能很多人对intern()这个函数不了解。JDK API文档中对intern()方法的描述是:</p>
<p><em>    返回字符串对象的规范化表示形式。<br>    一个初始为空的字符串池,它由类 String 私有地维护。</em></p>
<p><em>    当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。</em></p>
<p><em>    它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。</em></p>
<p><em>    所有字面值字符串和字符串赋值常量表达式都使用 intern 方法进行操作。</em></p>
<p>上面字符串池即为字符串常量池。明白该题结果的原因了吧。</p>
<p>6)false,false,true</p>
<p>第五题看明白后,第六题就没什么好讲的了。</p>
  </div>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值