如上例所述,变量a,b和它们的值10,20都是存在栈里面,声明的所以String类型的引用也都是存在栈里。而字符串abc是存在字符串常量池中,new出来的String对象则是存在堆里。

String str="abc";
System.out.print(str==str1);//true

上面这行代码被执行的时候,JVM先到字符串池中查找,看是否已经存在值为”abc”的对象,如果存在,则不再创建新的对象,直接返回已存在对象的引用;如果不存在,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。所以这句代码创建了一个对象

String str1="abc";
System.out.print(str==str2);//true

通过上面的解释这个就清楚了,在执行第二行代码时,”abc”字符串对象在常量池中已存在,所以直接返回池中已存在的那个字符串对象。

String str2="a"+"b"+"c";

由于常量字符串是在编译的时候就也被确定的,又因”a”,”b”和”c”都是常量,因此变量str2的值在编译时就可以确定。这行代码编译后的与String str=”abc”;是一样的,所以这句代码也是只创建了一个对象,但是这与我们平时好像不太一样啊?一般使用“+”连接两个字符串都会产生另一个新的字符对象。下面我们看一下下面这行代码就明白了:

String str3="c";
String str4="ab"+str3;
System.out.print(str==str4);//false
String str5="ab";
System.out.print(str==str6);//false

从上面例子我们就可以得出:使用“+”连接的两个字符串本身就是字面常量字符串时,如果池中存在这样连接后的字符串,则是不会重新创建对象,而是直接引用池中的字符串对象;如果“+”连接的两字符串中只要有一个不是字面常量串(即已经定义过的),会产生新的字符串对象(抛去特殊如final定义字符串不提)。
那我们来看一下有new创建字符串时会有什么不同:

String str7=new String("abc");  

首先、这行代码究竟创建了几个String对象呢?答案是2个。由于new String(“abc”)相当于”abc”,一个就是创建出来的放在堆的原实例对象,而另一个就是放在常量池中的 “aaa” 对象,当然这里的str7本身只是一个引用,放在栈里,用来指向堆中创建出来的对象。

String str7=new String("abc");
String str8=new String("abc");
System.out.print(str7.equals(str8));//true
System.out.print(str7==str8);//false
System.out.print(str==str7);//false

由于str7和str8是连个存在栈里的引用,他们分别创建了两个对象”abc”,虽然他们内容相同(str7.equals(str8)==true),但是实际存在物理地址不同,所以str7==str8值为false,同理,str指向常量池中的”abc”,所以str==str7也是false。

关于常量池,是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
(1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
(2)节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。

注意:常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(Symbolic References),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念。
所以当然常量池不只是表示字符串常量池,例如一些包装类都实现了常量池技术

基本类型和基本类型的包装类。基本类型有:byte、short、char、int、long、boolean。基本类型的包装类分别是:Byte、Short、Character、Integer、Long、Boolean(注意区分大小写)。
二者的区别是:基本类型体现在程序中是普通变量,基本类型的包装类是类,体现在程序中是引用变量。因此二者在内存中的存储位置不同:基本类型存储在栈中,而基本类型包装类存储在堆中
上边提到的这些包装类都实现了常量池技术,另外两种浮点数类型的包装类则没有实现
如下:

        Integer i1=10;
Integer i2=10;
Integer i3=new Integer(10);
Integer i4=new Integer(10);
System.out.print(i1==i2);//true
System.out.print(i2==i3);//false
System.out.print(i3==i4);//false
Double d1=1.0;
Double d2=1.0;
System.out.print(d1==d2);//false

案例分析:
1)i1和i2均是引用类型,在栈中存储指针,因为Integer是包装类。由于Integer包装类实现了常量池技术,因此i1和i2的10均是从常量池中获取的,均指向同一个地址,因此i1=12。
2)i3和i4均是引用类型,在栈中存储指针,因为Integer是包装类。但是由于他们各自都是new出来的,因此不再从常量池寻找数据,而是从堆中各自new一个对象,然后各自保存指向对象的指针,所以i3和i4不相等,因为他们所存指针不同,所指向对象不同。
3)d1和d2均是引用类型,在栈中存储指针,因为Double是包装类。但Double包装类没有实现常量池技术,因此Doubled1=1.0;相当于Double d1=new Double(1.0);,是从堆new一个对象,d2同理。因此d1和d2存放的指针不同,指向的对象不同,所以不相等。

JAVA String类型和原型模式的更多相关文章

  1. 【java设计模式】-06原型模式

    原型模式简述 定义: 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象 ,也就是通过复制现有对象实例产生新的对象,也就是所谓的"克隆" 实现方式: 1.实现Cl ...

  2. 《JAVA设计模式》之原型模式(Prototype)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办 ...

  3. java string类型的初始化

    以下基本上是java string类型最常用的三种方法 new string()就不介绍了  基本等同于第三种 String a;  申明一个string类型的 a,即没有在申请内存地址,更没有在内存 ...

  4. Java——string类型与date类型之间的转化

    String类型转化为Date类型 方法一 Date date=new Date("2019-01-25"); 方法二 String =(new SimpleDateFormat( ...

  5. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

  6. java设计模式-----5、原型模式

    原型(Prototype)模式是一种对象创建型模式,他采取复制原型对象的方法来创建对象的实例.使用原型模式创建的实例,具有与原型一样的数据. 原型模式的特点: 1.由原型对象自身创建目标对象.也就是说 ...

  7. 重学 Java 设计模式:实战原型模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 老板你加钱我的代码能飞 程序员这份工作里有两种人:一类是热爱喜欢的.一类是仅当成工作 ...

  8. 深度分析:java设计模式中的原型模式,看完就没有说不懂的

    前言 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的 ...

  9. java学习笔记之原型模式及深浅拷贝

    一.原型模式的基本介绍 在聊原型模式之前,我们来思考一个小问题,传统的方式我们是如何克隆对象呢? 那我们以多利羊(Sheep)为例,来说明上述这个问题,具体代码见下面: 多利羊(Sheep) publ ...

随机推荐

  1. 03-HTML的body标签(文本标签)学习

    <html> <head>  <title>HTML的body标签-文本标签学习</title>  <meta charset="utf ...

  2. Burnside引理与Polya定理

    感觉这两个东西好鬼畜= = ,考场上出了肯定不会qwq.不过还是学一下吧用来装逼也是极好的 群的定义 与下文知识无关.. 给出一个集合$G = \{a, b, c, \dots \}$和集合上的二元运 ...

  3. #WEB安全基础 : HTML/CSS | 0x8CSS进阶

    你以为自己学这么点CSS就厉害了? 学点新东西吧,让你的网页更漂亮 我们只需要用到图片和网页   这是index.html的代码 <html> <head> <title ...

  4. 外媒评李开复的《AI·未来》:四大浪潮正在席卷全球

    外媒评李开复的<AI·未来>:四大浪潮正在席卷全球 https://mp.weixin.qq.com/s/oElub0QOYjOROhqN3ULUkg [网易智能讯 9月17日消息]李开复 ...

  5. Tomcat安装教程

    Tomcat安装教程 文档下载:https://files-cdn.cnblogs.com/files/yocichen/Tomcat安装教程.rar 注意:本教程适用Windows平台安装Tomca ...

  6. 测者的测试技术笔记:揭开java method的一个秘密--巨型函数

    相信,很多人都不知道Java的Method的上限为64K.本文将超过这个上限的函数叫做巨型函数. 巨型函数的问题 1.如果代码超过了这个限制,Java编译器就报"Code too large ...

  7. Windbg学习笔记

    下载winsdksetup.exe ,双击,选择Debugging Tools for Windows安装. 64位系统抓64位进程dump,用64位windbg来分析.64位系统抓32位进程dump ...

  8. python优雅编程之旅

    偶然的机会坐上了python的贼船,无奈只能一步步踏上王者之巅..... 参考博客地址:https://mp.weixin.qq.com/s/OZVT3iFrpFReqdYqVhUf6g 1.交换赋值 ...

  9. AXI-Lite总线及其自定义IP核使用分析总结

    ZYNQ的优势在于通过高效的接口总线组成了ARM+FPGA的架构.我认为两者是互为底层的,当进行算法验证时,ARM端现有的硬件控制器和库函数可以很方便地连接外设,而不像FPGA设计那样完全写出接口时序 ...

  10. mysql 将一个表中的数据复制到另一个表中,sql语句

    1.表结构相同的表,且在同一数据库(如,table1,table2) Sql :insert into table1 select * from table2 (完全复制) insert into t ...