加入收藏 收藏网站 设为首页 设为首页
招生考试网
学历类| 阳光高考 研 究 生 自学考试 成人高考 专 升 本 中考会考 外语类| 四 六 级 职称英语 商务英语 公共英语 日语能力
资格类| 公 务 员 报 关 员 银行从业 司法考试 导 游 证 教师资格 财会类| 会 计 证 经 济 师 会计职称 注册会计 税 务 师
工程类| 一级建造 二级建造 造 价 师 造 价 员 咨 询 师 监 理 师 医学类| 卫生资格 执业医师 执业药师 执业护士 国际护士
计算机| 等级考试 软件水平 应用能力 其它类| 书画等级 美国高考 驾 驶 员 书法等级 少儿英语 报 检 员 单 证 员 出国留学
 招生考试网 - 计算机等级考试 - 考试辅导 - 正文

 
Java中的String:水深几许
来源:fjzsksw.com 2009-11-23 编辑:yangmeiling 【字体:小 大】

对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();//原先堆中的对象会变成垃圾。



 
  • 上一个文章:

  • 下一个文章:
  • 网站版权与免责声明
    ①由于各方面情况的不断调整与变化,本网所提供的相关信息请以权威部门公布的正式信息为准.
    ②本网转载的文/图等稿件出于非商业性目的,如转载稿涉及版权等问题,请在两周内来电联系.
    最新文章
    热门文章

    报名考试
    全国 | 黑龙江 | 吉林 | 辽宁 | 内蒙古
    青海 | 宁夏 | 甘肃 | 新疆 | 陕西
    西藏 | 北京 | 天津 | 河北 | 山东
    江苏 | 安徽 | 河南 | 上海 | 浙江
    福建 | 广东 | 山西 | 湖南 | 湖北
    江西 | 广西 | 海南 | 云南 | 贵州
    四川 | 重庆
    分省高校计算机考试
    黑龙江 | 吉林 | 辽宁 | 内蒙古 | 河北
    北京 | 天津 | 新疆 | 甘肃 | 宁夏
    青海 | 陕西 | 山西 | 河南 | 山东
    江苏 | 安徽 | 浙江 | 福建 | 广东
    海南 | 广西 | 江西 | 湖北 | 湖南
    四川 | 上海 | 重庆 | 贵州 | 云南
    西藏
    成绩查询
    报考指南
    试题答案
    模拟试题
    考试辅导
    计算机一级 | 计算机二级 | 计算机三级 | 计算机四级
    经验交流
    高校计算机