Question:String a = “abc”, String b = “abc”.String c = new String(“abc”);
if(a == b)
{system.out.println(“ok”);
}
if(a == c)
{system.out.println(“ok2”);
}
问会不会输出ok。
要想知道这个问题,就要了解Java虚拟机中的字符串分配。
首先,Java虚拟机包括堆区、栈区、方法区。堆区用来存放对象,比如Person a = new Person();堆区存放了new Person()这个对象。栈区存放了a这个指向new Person()对象的引用,此外,不属于对象的基本数据类型也存放在栈区中,比如 int a =1;这个a和1都存在栈区中。方法区,顾名思义就是存放类中的静态变量、类中的方法。
Java的String也是一个对象而不是数据类型,但是Java设计者给它特殊照顾了一下,在堆区有一块空间是专门为它开辟的叫String pool(String池)。String pool跟栈区有点类似,当我们存储了一个字符串时,虚拟机会为这个字符串分配一个引用存在string pool中,这个引用指向该字符串。
再来看这道题,首先存放了一个abc在堆区中,string pool立马记住了这个叫abc的字符串,当新生成一个b的字符串也叫abc时,虚拟机首先会在string pool中寻找看这个abc的字符串在不在,显然它是在的,所以b这个引用直接指向了和a一样的地址,故这个if是true,会输出ok。但是c直接new了一个string,直接绕过了string pool的检查,直接在堆区中开辟一块新的空间,尽管两块空间的内容都是abc。因此第二个if是false,不会输出ok2。
从上述内容我们可以发现,String a = "abc"比new的方式更节省空间。
Java字符串在内存中的分配情况
最新推荐文章于 2024-06-01 13:41:45 发布