REF: http://blog.csdn.net/fightforyourdream/article/details/15333405

题目是一道简单的小程序,像下面这样:
[java] view plaincopy
public class Test1 {  
 public static void main(String args[]) {  
  String s = new String("Hello");  
  System.out.println(s);  
 
  foo(s);  
  System.out.println(s);  
 }  
 
 public static void foo(String s) {  
  s = new String("World");  
 }  
}

问程序先后两次分别会输出什么。
第一个肯定输出“Hello”。关键是第二个,个别基础不牢的朋友可能被考倒,但基础稍微扎实一点的就不会。第二个输出的也是“Hello”。
到这里,万事大吉。面试官两眼放出喜悦的光芒,赞叹道:“嗯,不错不错。不会变的,对吧。因为String是immutable类型,immutable类型改不了的。”他说的“immutable”是指String类没有任何一个方法会改变对象的状态。
 
这可就有问题了。确实程序两次输出的都是“Hello”,但原因却不是String的immutable特性。不信换一个“mutable”的试试,比如StringBuilder或StringBuffer。

[java] view plaincopy
public class Test2 {  
 public static void main(String args[]) {  
  StringBuilder s = new StringBuilder("Hello");  
  System.out.println(s);  
 
  foo(s);  
  System.out.println(s);  
 }  
 
 public static void foo(StringBuilder s) {  
  s = new StringBuilder("World");  
 }  
}

这次呢?会先输出“Hello”,然后输出“World”吗?不会,仍然是两次“Hello”。
足以说明这个问题跟String的immutable特性没有一毛钱的关系。不管是immutable类型,还是一般的类型,用这种方式写出来的程序main方法中前后两个对象肯定是一样的。
 
真正的原因是:Java语言的参数传递机制是“按值传递”(pass by value)。虽然Java中除基本数值类型外,其它变量都是引用,但那是另一回事。变量的语义(“引用”还是“值”)跟函数传参的机制是两个正交的概念。
各种编程语言中,最常见的参数传递方式不外乎按值传递和按引用传递(pass by reference)两种。比如,C和Java中函数参数都是按值传递的,C++和C#则同时支持按值传递和按引用传递。C和Java的不同在于,C是值类型的按值传递,而Java是引用类型的按值传递(基本的数值类型除外)。
按值传参最大的特点就是函数内部对“形参变量”本身的所做的修改外面的“实参变量”感知不到。
 
不过,对于StringBuilder来说我们至少有办法让它改变,比如像下面这样:

[java] view plaincopy
public class Test3 {  
 public static void main(String args[]) {  
  StringBuilder s = new StringBuilder("Hello");  
  System.out.println(s);  
 
  foo(s);  
  System.out.println(s);  
 }  
 
 public static void foo(StringBuilder s) {  
  s.replace(0, s.length(), "World");  
 }  
}

体会到不同了吗?虽然参数变量本身是按值传递的,但这次我们对变量本身不感兴趣,我们不改变变量本身,而是通过它直接修改它所引用的那个对象。这一次,Java语言“几乎一切皆引用”的特点起作用了,程序第一次输出“Hello”,第二次输出“World”。熟悉C的朋友可能马上联想到:这很像C语言中通过指针来修改它指向的内容。
而先前那个String版本的程序,我们无法写出一个相应的可变版本。为什么呢?……“嗯,不错不错。因为String是immutable类型……”,这次真对了。——可见先前说“没有一毛钱的关系”也不尽然。因为immutable,导致我们无法针对String写出一个像Test3那样的“可变”程序,如此说来,“二分钱的关系”应该是有的。
 
“pass reference by value”就像C++ 11中的“An lvalue with rvalue reference type”一样,乍一看挺绕的,但只要仔细想清楚,让正交的东西“尘归尘 土归土”,就可以加深对语言的理解。
顺便问一句,您知道java.lang.StringBuilder和java.lang.StringBuffer的区别吗?好多面试官都喜欢“顺便”问问这个,而且答对了不会加分,答不上来却会扣分,至少扣印象分。:(

java.lang.StringBuilder和java.lang.StringBuffer的区别:
StringBuffer is synchronized, StringBuilder is not.
StringBuilder is faster than StringBuffer because it's not synchronized.

看来以前喜欢用StringBuffer不是个好习惯,以后要多用StringBuilder !!!

这也让我想到了另一个经典的问题:Hashtable和HashMap的区别是什么?
Hashtable is synchronized, whereas HashMap is not. This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.
Hashtable does not allow null keys or values. HashMap allows one null key and any number ofnull values.
One of HashMap's subclasses is LinkedHashMap, so in the event that you'd want predictable iteration order (which is insertion order by default), you could easily swap out the HashMap for aLinkedHashMap. This wouldn't be as easy if you were using Hashtable.
Since synchronization is not an issue for you, I'd recommend HashMap. If synchronization becomes an issue, you may also look at ConcurrentHashMap.

总之都是unsynchronized要快一些,但鉴于Hashtable这个概念在面试中比HashMap来的多得多,所以在做面试题时还是用Hashtable吧,在项目开发中我从来都是用HashMap.

Ref:
http://blog.csdn.net/steedhorse/article/details/6892569
http://stackoverflow.com/questions/355089/stringbuilder-and-stringbuffer-in-java
http://vanillajava.blogspot.de/2013/04/why-synchronized-stringbuffer-was-never.html
http://stackoverflow.com/questions/40471/differences-between-hashmap-and-hashtable

【转载】关于Java String, StringBuilder, StringBuffer, Hashtable, HashMap的面试题的更多相关文章

  1. Java String StringBuilder StringBuffer

    String是字符串常量 StringBuilder和StringBuffer都是字符串变量 速度方面:StringBuilder > StringBuffer > String 每当用S ...

  2. Java - String, Stringbuilder, StringBuffer比较

    http://www.cnblogs.com/zuoxiaolong/p/lang1.html

  3. java中String StringBuilder StringBuffer比较和效率(性能)测试

    string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...

  4. JAVA String、StringBuffer、StringBuilder类解读

    JAVA String.StringBuffer.StringBuilder类解读 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作 ...

  5. 深入源码剖析String,StringBuilder,StringBuffer

    [String,StringBuffer,StringBulider] 深入源码剖析String,StringBuilder,StringBuffer [作者:高瑞林] [博客地址]http://ww ...

  6. String, StringBuilder, StringBuffer问题

    1. 区别 String为字符串常量,而StringBuilder和StringBuffer都是字符串变量,其中StringBuilder线程非安全,StringBuffer线程安全. 每次对 Str ...

  7. String StringBuilder StringBuffer区别

    String StringBuilder StringBuffer String类是final类,不可以被继承,且它的成员方法也是final方法,当一个字符串对象进行操作操作时,任何的改变不会影响到这 ...

  8. difference among String,StringBuilder,StringBuffer

    difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...

  9. JDK源码分析系列---String,StringBuilder,StringBuffer

    JDK源码分析系列---String,StringBuilder,StringBuffer 1.String public final class String implements java.io. ...

随机推荐

  1. lsof命令详解(转)

    lsof命令详解(转) 上一篇 / 下一篇  2011-06-09 21:56:41 / 个人分类:Linux 查看( 351 ) / 评论( 0 ) / 评分( 0 / 0 ) 在Linux中,ls ...

  2. easymock快速入门

    easymock是众多mock之中的很容易用的mock,今天刚开始学习,来个简单的教程.以购物车结算为例子,比如首先是每一个商品项的pojo. public class Item { private ...

  3. java 图片与文字生成PDF

    1.jar包:iText-2.1.5.jar 2.code: import java.awt.Color; import java.io.File; import java.io.FileNotFou ...

  4. MFC的DLL中实现定时器功能

    方法一:创建一个线程, 反复读系统时间不就可以了? 如果定时要求不严,用Sleep就可以了.DWORD WINAPI TimerThread(LPVOID pamaram) { UINT oldTic ...

  5. 如何打开Intellij IDEA的代码提示功能/联想/自动联想

    1.默认情况下,我们输入代码时IDEA会自动弹出代码提示框,这时候是不用按快捷键的,直接使用方向键选择我们需要的条目就可以了. 2:如果我们想主动 使用代码提示时,默认的快捷键是CTRL+空格,但是中 ...

  6. Nginx 在ubuntu14.04下的安装

    来源:http://blog.csdn.net/hanshileiai/article/details/45580001 按照步骤一步一步来,绝对ok 1.如果出现错误: *4 connect() t ...

  7. Android权限详解

    在Android的设计中,资源的访问或者网络连接,要得到这些服务都需要声明其访问权限,否则将无法正常工作.在Android中这样的权限有很多种,这里ATAAW.COM将各类访问权限一一罗列出来,供大家 ...

  8. ASP.NET MVC同时支持web与webapi模式

    原文地址:https://blog.csdn.net/laymat/article/details/65444701 我们在创建 web mvc项目时是不支持web api的接口方式访问的,所以我们需 ...

  9. Mac 安装任何来源的文件

    1.Mac 安装任何来源的文件 安装软件提示文件损坏怎么处理,打开 DMG 文件提示损坏怎么处理,来自不信任的开发者怎么处理,macOS Sierra 如何安装任何来源的文件. 非常肯定的告诉您不是我 ...

  10. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...