在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程序猿面试笔试宝典官网

《Java程序猿面试笔试宝典》之字符串创建与存储的机制是什么的更多相关文章

  1. 《Java程序员面试笔试宝典》终于在万众期待中出版啦~

    <Java程序员面试笔试宝典>终于在万众期待中出版啦~它是知名畅销书<程序员面试笔试宝典>的姊妹篇,而定价只要48元哦,恰逢求职季节,希望本书的出版能够让更多的求职者能够走进理 ...

  2. 《Java程序员面试笔试宝典》之为什么需要public static void main(String[] args)这个方法

    public staticvoid main(String[] args)为Java程序的入口方法,JVM在运行程序的时候,会首先查找main方法.其中,public是权限修饰符,表明任何类或对象都可 ...

  3. 《Java程序员面试笔试宝典》之Java程序初始化的顺序是怎样的

    在Java语言中,当实例化对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在类的构造函数创建对象. Java程序的初始化一般遵循以下三个原则(以下三原则优 ...

  4. JAVA程序员面试笔试宝典1

    1.为什么Java中有些接口没有任何方法? 这些没有任何方法声明的接口又被称为标识接口,标识接口对于实现它的类没有任何语义上的要求,它仅仅充当一个标识的作用,用来表明它的类属于一个特定的类型. 2.j ...

  5. 《Java程序员面试笔试宝典》之字符串创建与存储的机制是什么

    在Java语言中,字符串起着非常重要的作用,字符串的声明与初始化主要有如下两种情况: (1)       对于String s1=new String("abc")语句与Strin ...

  6. 《Java程序员面试笔试宝典》之switch使用时有哪些注意事项

    switch语句用于多分支选择,在使用switch(expr)的时候,expr只能是一个枚举常量(内部也是由整型或字符类型实现)或一个整数表达式,其中整数表达式可以是基本类型int或其对应的包装类In ...

  7. 《Java程序员面试笔试宝典》之Static关键字有哪些作用

    static关键字主要有两种作用:第一,只想为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关.第二,希望某个方法或属性与类而不是对象关联在一起,也就是说,在不创建对象的情况下就可以通过 ...

  8. 《Java程序员面试笔试宝典》之Java与C/C++有什么异同

    Java与C++都是面向对象语言,都使用了面向对象思想(例如封装.继承.多态等),由于面向对象有许多非常好的特性(继承.组合等),使得二者都有很好的可重用性. 需要注意的是,二者并非完全一样,下面主要 ...

  9. 《Java程序员面试笔试宝典》之为什么Java中有些接口没有任何方法

    由于Java不支持多重继承,即一个类只能有一个父类,为了克服单继承的缺点,Java语言引入了接口这一概念.接口是抽象方法定义的集合(接口中也可以定义一些常量值),是一种特殊的抽象类.接口中只包含方法的 ...

  10. 《Java程序员面试笔试宝典》之组合与继承有什么区别

    组合和继承是面向对象中两种代码复用的方式.组合是指在新类里面创建原有类的对象,重复利用已有类的功能.继承是面向对象的主要特性之一,它允许设计人员根据其它类的实现来定义一个类的实现.组合和继承都允许在新 ...

随机推荐

  1. PHP开发之旅-表单验证

    一.创建表单 <form name = "login" method = "post" action="contact.php?action=l ...

  2. Leetcode0523--Continuous Subarray Sum 连续和倍数

    [转载请注明]https://www.cnblogs.com/igoslly/p/9341666.html class Solution { public: bool checkSubarraySum ...

  3. html5——盒子模式

    box-sizing属性 box-sizing: border-box;/*内减模式*/ box-sizing: content-box;/*外加模式(默认值)*/ box-sizing: paddi ...

  4. easyui 使用笔记

    http://www.easyui.info/archives/1435.html datagrid 服务端分页 服务端分页,高效,快捷!强力推荐! easyui的datagrid服务端分页,通过设置 ...

  5. Cuder - 用C++11封装的CUDA类

    以前写cuda:初始化环境,申请显存,初始化显存,launch kernel,拷贝数据,释放显存.一个页面大部分都是这些繁杂但又必须的操作,有时还会忘掉释放部分显存. 今天用C++11封装了这些CUD ...

  6. C# 处理URL地址

    calendarset.do?start=1548518400&end=1552147200&_=1546421856958calendarset.do?start=155093760 ...

  7. * 获取页面参数 * @return 参数打印

    /** * 获取页面参数 * @return 参数打印 */ GetUrlParam: function(paraName) { var url = document.location.toStrin ...

  8. 在对话框添加bitmap

    CBitmap bitmap; //加载指定位图资源 Bmp图片ID bitmap.LoadBitmap(IDB_BITMAP1); //获取对话框上的句柄 图片控件ID CStatic *p = ( ...

  9. 让System.Drawing.Bitmap可以在linux运行

    .net core的bitmap使用的是以下类库,但无法在linux运行 https://github.com/CoreCompat/CoreCompat 在linux运行需要安装runtime.li ...

  10. Centos初始化硬盘分区、挂载

    刚刚买了一台服务器,刚买的服务器的数据盘都是需要自己来分区的,下面就记录一下操作. 通过命令fdisk-l查看硬盘信息 可以看到有两块硬盘/dev/vda和/dev/vdb,启动vda是系统盘vdb是 ...