在Java语言中。字符串起着非常关键的数据。字符串的声明与初始化主要有例如以下两种情况:
(1) 对于String s1=new String(“abc”)语句与String s2=new String(“abc”)语句,存在两个引用对象s1、s2,两个内容同样的字符串对象”abc”。它们在内存中的地址是不同的。仅仅要用到new总会生成新的对象。

(2) 对于String s1 = “abc”语句与String s2 = “abc”语句。在JVM中存在着一个字符串池,当中保存着非常多String对象,并且能够被共享使用,s1、s2引用的是同一个常量池中的对象。因为String的实现採用了Flyweight的设计模式。当创建一个字符串常量的时候。比如String s = “abc”,会首先在字符串常量池中查找是否已经有同样的字符串被定义,它的推断根据是String类equals(Object obj)方法的返回值。

假设已经定义,则直接获取对其的引用,此时不须要创建新的对象,假设未定义,则首先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。

因为String是不可变类,一旦创建好了就不能被改动,因此String对象能够被共享并且不会导致程序的混乱。
详细而言:
String s=“abc”; //把“abc”放到常量区中,在编译时产生。
String s=“ab”+”c”; //把“ab”+“c”转换为字符串常量“abc”放到常量区中。
String s=new String(“abc”); //在执行时把“abc”放到堆里面的。
比如:
String s1=“abc”; //在常量区里面存放了一个”abc”字符串对象
String s2=“abc”; //s2引用常量区中的对象,因此不会创建新的对象
String s3=new String(“abc”) //在堆中创建新的对象
String s4=new String(“abc”) //在堆中又创建一个新的对象
为了便于理解。能够把String s = new String(“abc”)语句的执行人为地分解成两个过程:第一个过程是新建对象的过程,即new String(“abc”),第二个过程是赋值的过程,即String s=。

因为第二个过程中仅仅是定义了一个名为s的String类型的变量,将一个String类型对象的引用赋值给s,因此在这个过程中不会创建新的对象。

第一个过程中new String(“abc”)会调用String类的构造函数:
public String(String original){
//body
}
在调用这个构造函数的时候,传入了一个字符串常量。因此语句new String(“abc”)也就等价于”abc”和new String()两个操作了。假设在字符串池中不存在”abc”。则会创建一个字符串常量”abc”,并将其加入到字符串池中,假设存在。则不创建。然后new String()会在堆中创建一个新的对象。所以str3与str4指向的是堆中不同的String对象,地址自然也不同样了。

如图 5 5所看到的。

下图两种字符串存储方式

引申:对于String类型的变量s。赋值语句s=null与s=“”是否同样?
对于赋值语句s=null,当中s是一个字符串类型的引用,它不指向不论什么一个字符串。而赋值语句s=“”中 s是一个字符串类型的引用,它指向另外一个字符串(这个字符串的值为“”,即空字符串)。
常见笔试题:
new String(“abc”)创建了几个对象?
答案:一个或两个。假设常量池中原来有“abc”,那么仅仅创建一个对象,假设常量池中原来没有字符串“abc”,那么就会创建两个对象。

出自

p=180">Java程序猿面试笔试宝典官网

最新文章

  1. Ext JS 4 新特性2:配置项属性(config)之二
  2. wampserver 403 禁止访问
  3. 假期实践作业:从IT角度看地铁
  4. 【BZOJ-2756】奇怪的游戏 最大流 + 分类讨论 + 二分
  5. -webkit-text-size-adjust
  6. 从输入 URL 到页面加载完的过程中都发生了什么事情?
  7. Oracle执行语句跟踪(2)——使用10046事件实现语句追踪
  8. CMDB反思4
  9. 函数buf_LRU_add_block
  10. Java [leetcode 5] Longest Palindromic Substring
  11. PHP中的魔术方法总结 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep, __wakeup, __toStr
  12. C# 当前程序所有线程
  13. js中__proto__(内部原型)和prototype(构造器原型)的关系
  14. Tri_integral Summer Training 5 总结
  15. 复杂SQL代码实例
  16. [译]Selenium Python文档:七、WebDriver API接口
  17. 利用shell脚本监控目录内文件改动
  18. Python 获取当前脚本文件路径目录
  19. 【RL-TCPnet网络教程】第17章 RL-TCPnet之UDP通信
  20. 【APIO2016】【UOJ205】【LOJ2568】烟花表演 可合并堆

热门文章

  1. org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException。
  2. 336 Palindrome Pairs 回文对
  3. 【原】cocos2d-x开发笔记:获取Sprite上某一个点的透明度,制作不规则按钮
  4. 记Spring下autowire为name时的一个现象
  5. NetBeans将java项目编译成jar包
  6. postfix 邮件中继配置
  7. VBA/VBScript提取Word(*.doc)文件中包含的图片(照片)
  8. CWnd* pParent
  9. vue学习笔记(六)— 关于Vuex可以这样简单理解
  10. [测试工具]----iperf