意见反馈 Java认证首页 返回顶部
您现在的位置:考试大 >> Java认证考试资格考试 >> 专业语言 >> 文章内容

Java核心之Java内存分配原理

来源:考试大   【考试大:中国教育考试门户】   2011年7月13日

  String常量池问题的几个例子

  下面是几个常见例子的比较分析和理解:

  String a = "a1";

  String b = "a" + 1;

  System.out.println((a == b)); //result = true

  String a = "atrue";

  String b = "a" + "true";

  System.out.println((a == b)); //result = true

  String a = "a3.4";

  String b = "a" + 3.4;

  System.out.println((a == b)); //result = true

  分析:JVM对于字符串常量的"+"号连接,将程序编译期,JVM就将常量字符串的"+"连接优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序终的结果都为true。

  String a = "ab";

  String bb = "b";

  String b = "a" + bb;

  System.out.println((a == b)); //result = false

  分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来报考分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。

  String a = "ab";

  final String bb = "b";

  String b = "a" + bb;

  System.out.println((a == b)); //result = true

  分析:和[3]中一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量 池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。

  String a = "ab";

  final String bb = getBB();

  String b = "a" + bb;

  System.out.println((a == b));

  //result = false

  private static String getBB() {

  return "b";

  }

  分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来报考连接并分配地址为b,故上面 程序的结果为false。

  通过上面4个例子可以得出得知:

  String s = "a" + "b" + "c";  就等价于

  String s = "abc";

  String a = "a";

  String b = "b";

  String c = "c";

  String s = a + b + c;

  这个就不一样了,终结果等于:

  StringBuffer temp = new StringBuffer();

  temp.append(a).append(b).append(c);

  String s = temp.toString();

  由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:

  public class Test {

  public static void main(String args[]) {

  String s = null;

  for(int i = 0; i < 100; i++) {

  s += "a";

  }

  }

  }

  每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行 append操作。

  String对象的intern方法理解和分析:

  public class Test4 {

  private static String a = "ab";

  public static void main(String[] args){

  String s1 = "a";

  String s2 = "b";

  String s = s1 + s2;

  System.out.println(s == a);//false

  System.out.println(s.intern() == a);//true

  }

  }

  这里用到JAVA里面是一个常量池的问题。对于s1+s2操作,其实是在堆里面重新创建了一个新的对象,s保存的是这个新对象在堆空间的的内容,所 以s与a的值是不相等的。而当调用s.intern()方法,却可以返回s在常量池中的地址值,因为a的值存储在常量池中,故s.intern和a的值相等。

  总结

  栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容堆中存放使用new关键字创建的对象.字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常 量池中,而有的是运行时才被创建.使用new关键字,存放在堆中。

  考试大温馨提示:本内容来源于网络,仅代表作者个人观点,与本站立场无关,仅供您学习交流使用。其中可能有部分文章经过多次转载而造成文章内容缺失、错误或文章作者不详等问题,请您谅解。如有侵犯您的权利,请联系我们,本站会立即予以处理。

  编辑特别推荐:

  Java认证如何查看ControlFile中的内容

  Java中基本数据类型与应用

  Servlet中的八大Listener

来源:考试大-Java认证

责编:xxm  评论 纠错

上一页123下一页

模板不存在,请添加模板后再生成!E:\wwwroot\www_233_com\Templets\three\Templets\soft\small\cont_b_st.htm
网友跟贴

暂无跟贴,欢迎您发表意见

 
 
跟贴共0
笔 名 :
网友评论仅供其表达个人看法,并不表明考试大同意其观点或证实其描述
处理 SSI 文件时出错