堆与栈

Java的堆是一个运行时数据区,对象从中分配空间。这些对象通过new、newarray、anewarray和multianewarray等指令建立,它们不需要程序代码来显式地释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。

栈的优势是,存取速度比堆要快,仅次于寄存器,栈数据可以共享。但缺点是,存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量数据(int,short,long,byte,float,double,boolean,char)和对象引用。

栈有一个很重要的特殊性,就是存在栈中的数据可以共享。假设我们同时定义:

Java代码

int a = 3;

int b = 3;

编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存放进来,然后将a指向3。接着处理int b = 3;在创建完b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3。这样,就出现了a与b同时均指向3的情况。

这时,如果再令 a=4;那么编译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址。因此a值的改变不会影响到b的值。

要注意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b,它是由编译器完成的,它有利于节省空间。

字符串

1. 首先String不属于8种基本数据类型,String是一个对象。因为对象的默认值是null,所以String的默认值也是null。但它又是一种特殊的对象,有其它对象没有的一些特性。

2. new String()和new String("")都是申明一个新的空字符串,是空串不是null。

3. String str="kvill"和String str=new String("kvill")的区别

示例:

Java代码

String s0="kvill";

String s1="kvill";

String s2="kv" + "ill";

System.out.println(s0==s1);

System.out.println(s0==s2);

结果为:

true

true

首先,我们要知结果为道Java会确保一个字符串常量只有一个拷贝。

因为例子中的s0和s1中的"kvill"都是字符串常量,它们在编译期就被确定了,所以s0==s1为true。而"kv"和"ill"也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中"kvill"的一个引用。所以我们得出s0==s1==s2。用new String()创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

示例:

Java代码

String s0="kvill";

String s1=new String("kvill");

String s2="kv" + new String("ill");

System.out.println(s0==s1);

System.out.println(s0==s2);

System.out.println(s1==s2);

结果为:

false

false

false

例2中s0还是常量池中"kvill"的应用,s1因为无法在编译期确定,所以是运行时创建的新对象"kvill"的引用,s2因为有后半部分new String("ill")所以也无法在编译期确定,所以也是一个新创建对象"kvill"的应用。

4. String.intern()

再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的 intern()方法就是扩充常量池的一个方法。当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用。

示例:

Java代码

String s0= "kvill";String s1=new String("kvill");

String s2=new String("kvill");System.out.println(s0==s1);

System.out.println("**********");

s1.intern();s2=s2.intern();

System.out.println(s0==s1);

System.out.println(s0==s1.intern());

System.out.println(s0==s2);

结果为:

false

**********"

false //虽然执行了s1.intern(),但它的返回值没有赋给s1

true //说明s1.intern()返回的是常量池中"kvill"的引用

true

5. 关于equals()和==

这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true。而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。

6. 关于String是不可变的

这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了。比如说:String str="kv"+"ill"+" "+"ans"; 就是有4个字符串常量,首先"kv"和"ill"生成了"kvill"存在内存中,然后"kvill"又和" "生成 "kvill"存在内存中,最后又和"ans"生成了"kvill ans";并把这个字符串的地址赋给了str,就是因为String的"不可变"产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。

下面是一些String相关的常见问题:

String中的final用法和理解

Java代码

final StringBuffer a = new StringBuffer("111");

final StringBuffer b = new StringBuffer("222");

a=b;//此句编译不通过

final StringBuffer a = new StringBuffer("111");

a.append("222");//编译通过

可见,final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译器错误。至于它所指向的对象的变化,final是不负责的。

总结

栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String、数组、对象等等)但不存放对象内容。

堆中存放使用new关键字创建的对象。

字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定义(常量池和堆)。有的是编译期就已经创建好,存放在字符串常量池中,而有的是运行时才被创建。

java string 栈_Java堆和栈的区别(String类)相关推荐

  1. java 堆 栈 ===_Java堆,栈,堆栈

    栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量.栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器 在java中,所有基本类型和引用类型都在栈中存储. ...

  2. java的堆和栈_Java 堆和栈的区别

    1.概述 在Java中,内存分为两种,一种是栈内存,另一种就是堆内存. 2.堆内存 1.什么是堆内存? 1 堆内存是是Java内存中的一种,它的作用是用于存储Java中的对象和数组,当我们new一个对 ...

  3. java 内存机制(堆和栈),内存地址

    为什么80%的码农都做不了架构师?>>>    问题的引入: 问题一: String str1 = "abc"; String str2 = "abc& ...

  4. 定义入栈java_Java堆和栈你敢说了解吗?看完这个文章再有底气说吧

    Java中堆和栈的理解要求特别深刻,所以我们重点写了一个堆和栈的区别的文章,方便大家理解和应用. JAVA,内存模型中堆和栈的区别 在了解Java堆和栈的区别之前,我们先了解一下内存分配策略. JAV ...

  5. mysql中堆和栈_堆和栈 - 矮油~ - 博客园

    在计算机领域,堆栈是一个不容忽视的概念,我们编写的C语言程序基本上都要用到.但对于很多的初学着来说,堆栈是一个很模糊的概念. 堆栈:一种数据结构.一个在程序运行时用于存放的地方,这可能是很多初学者的认 ...

  6. java 常量池 和 堆 的关系_Java堆、栈和常量池以及相关String的详细讲解(经典中的经典)...

    博客分类: Java综合 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方--处理器内部.但是寄存器的数量极其有 ...

  7. Java内存分配之堆、栈和常量池(转)

    摘录自http://www.cnblogs.com/SaraMoring/p/5687466.html Java内存分配主要包括以下几个区域: 1. 寄存器:我们在程序中无法控制 2. 栈:存放基本类 ...

  8. java什么是栈_java什么是栈

    系统中的堆.栈和数据结构堆.栈不是一个概念.可以说系统中的堆.栈是真实的内存物理区,数据结构中的堆.栈是抽象的数据存储结构. 栈:实际上就是满足后进先出的性质,是一种数据项按序排列的数据结构,只能在一 ...

  9. java面试 内存中堆和栈的区别

    java中的内存,分为两种,一为堆内存,二为栈内存. 栈内存 在函数中定义的基本类型的变量和对象的引用变量都是在函数的栈内存中分配. 当在一段代码块中声明了一个变量时,java就会在栈内存中为这个变量 ...

最新文章

  1. 阿里数据产品经理工作(总结篇):数据PD,做牛做马
  2. 师范类专业物理和计算机选哪个,师范专业太多,哪些师范专业含金量高?资深教师:选这4个就对了...
  3. android: 播放音频
  4. react jest测试_如何使用Jest和react-testing-library测试Socket.io-client应用程序
  5. 作者:林嘉洺(1992-),男,华南师范大学计算机学院硕士生。
  6. 还要我带一个六级辅导班--痛苦!
  7. C++ 3D物理引擎库BulletPhysics基本使用
  8. 如何使用python进行批处理
  9. drool-6.5的自学demo
  10. oracle11g 官网下载链接
  11. [RS] 地理空间数据云 使用ftp批量下载影像(以批量下载Landsat8数据为例)
  12. CATIA软件常见问题解答
  13. 360面临两线作战----手机安全领域硝烟再起
  14. 利用TravisCI持续集成自动测试GitHub项目
  15. SIRO Challenge 状态压缩 + DP 未解
  16. 科学计算机统计说明书,科学计算器的使用方法
  17. 在字符串中输入回车换行或其它特殊字符
  18. 数据库之Mac下Mysql命令全集
  19. 5G 与 MEC 边缘计算
  20. Excel公式大全【300函数】

热门文章

  1. s3 java_java – 我们可以迭代Amazon S3中的完整对象集
  2. 基于JAVA+SpringMVC+MYSQL的简单企业人事管理系统
  3. 基于JAVA+SpringBoot+Mybatis+MYSQL的实验室预约信息管理系统
  4. java task和thread_【Java学习笔记-并发编程】线程与任务
  5. Java 并发系列之十三:安全发布
  6. AlexNet,VGG,GoogleNet,ResNet
  7. Routing a Marathon Race
  8. Java开发笔记(五十六)利用枚举类型实现高级常量
  9. html5中新增的语义化的标签
  10. js实现ajax的post请求步骤