设为首页 加入收藏

TOP

Java中的String:水深几许
2014-11-23 22:03:21 】 浏览:297
Tags:Java String: 水深 几许

  对Java中String的理解一直源于C++中的String,但越来越不对劲。


  从字符串常量到String对象,到地址池的引出,再到Java中内存的分类,再到上一篇中讲到的Java编译器的优化,最后到《java语言规范》。


  刚刚开始学Java,遇到这种问题,不知道是该庆幸呢,还是愈发感到忧烦。但个人还是倾向于前者,任何疑惑都有可能是一个起点,引向一片新的未知世界。从这个起点开始,可能会有更多的疑惑,但要解决这些疑惑,给自己一个基本满意的交代(最起码把疑惑给干掉),一直顺藤摸瓜下去,终究会有一个尽头,而这个过程,对于刚刚开始学的我来说将是一个很好的学习契机。


  ――――――――――――――――――――――――――――――――


  C++中的String:


  字符串常量:本质上有一个const char* pstr就可以表征了;


  String类:自定义类,通过重载+,=等运算符,实现其功能;


  一切很清晰明了。


  Java中的String:


  (某本教材)所有用双引号括起的字符串常量(又称作字面常数)都被认为是对象。


  在Java中引用类型变量间用==,判别2个引用类型变量是否是同一对象的引用。Java中没有运算符的重载(只有对于String的+,从不同层面上看可以理解是运算符的重载与否)。


  于是乎,关于String ,==,+,=的各种问题混乱不堪。


  ――――――――――――――――――――――――――――――――


  Process:


  不清楚String str="abc";时看到了地址池的概念,于是乎寻找有关Java内存分配的内容。找到一篇还不错的文章:


  http://zy19880423.javaeye.com/blog/434179


  Java内存分配:


  1. 寄存器:我们在程序中无法控制;


  2. 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而


  是存放在堆中;


  3. 堆:存放用new产生的数据;


  4. 静态域:存放在对象中用static定义的静态成员;


  5. 常量池:存放常量;


  6. 非RAM存储:硬盘等永久存储空间。


  Tips:


  引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。引用变量就相当于是为数组或者对象起的一个名称。引用变量是普通的变量,定义时在栈中分配,引用变量在程序运行到其作用域之外后被释放。 (其实就是Java中的指针)。


  数组和对象本身在堆中分配,即使程序运行到使用 new 产生数组或者对象的语句所在的代码块之外,数组和对象本身占据的内存不会被释放,数组和对象在没有引用变量指向它的时候,才变为垃圾,不能在被使用,但仍然占据内存空间不放,在随后的一个不确定的时间被垃圾回收器收走(释放掉)。这也是Java比较占内存的原因。(不像C++中那样,临时对象在程序运行到代码段外时会被立即析构掉,所以,返回临时对象的指针是危险的!)(Java则例外,可以返回临时对象,如果赋值给一个外部变量,则该对象仍然继续存在,不会被回收,只是其临时引用变量被干掉而已)。


  常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。虚拟机必须为每个被装载的类型维护一个常量池。常量池就是该类型所用到常量的一个有序集和,包括直接常量(string,integer和 floating point常量)和对其他类型,字段和方法的符号引用。对于String常量,它的值是在常量池中的。而JVM中的常量池在内存当中是以表的形式存在的,对于String类型,有一张固定长度的CONSTANT_String_info表用来存储文字字符串值。在程序执行的时候,常量池会储存在 Method Area,而不是堆中。


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


  如果原先str引用的是堆中的对象:


  str=str.intern();//原先堆中的对象会变成垃圾。


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java中基本数据类型默认值 下一篇几个著名Java开源缓存框架介绍

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目