温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java内存分配原理是什么

发布时间:2021-12-01 14:04:09 来源:亿速云 阅读:85 作者:iii 栏目:编程语言

本篇内容介绍了“Java内存分配原理是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

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的值相等。

“Java内存分配原理是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI