java中String对象的存储位置
转载注明出处:https://www.cnblogs.com/carsonwuu/p/9752949.html
本次样例中使用6个test直接演示String对象的创建位置:堆、栈、常量池。
1 package test.string.equal; 2 3 public class Main { 4 5 /** 创建了三个对象,"helloworld对象创建在常量池中",每次new String()都会创建一个对象在堆内存中工两个堆对象。 6 * 7 */ 8 void test() { 9 String s1= new String("helloworld"); 10 String s2= new String("helloworld"); 11 } 12 /**程序只创建一个字符串对象“Java”,存放在常量池中,所以s1==s2 为true 13 * 14 */ 15 void test1(){ 16 String s1="Java"; 17 String s2="Java"; 18 System.out.println(s1==s2); 19 } 20 21 /** 第一个new String("Java"):创建了两个对象,Java创建于常量池中,String对象创建于堆内存中。 22 * 第二个new String("Java"):由于常量池中有Java对象,所以只需创建一个对象,String对象创建于堆内存中。 23 * s1与s2分别指向String对象堆内存,所以s1==s2 为false 24 */ 25 void test2() { 26 String s1=new String("Java"); 27 String s2= new String("Java"); 28 System.out.println(s1==s2); 29 } 30 31 /** 常量的值在编译的时候就确定了,"hello"、"world"都是常量,因此s2的值在编译的时候也确定了, 32 * s2指向常量池中的"hello world",所以s1==s2为true 33 * 34 */ 35 void test3() { 36 String s1="hello world"; 37 String s2="hello "+"world"; 38 System.out.println(s1==s2); 39 } 40 41 /** s4由两个String变量相加得到,不能再编译时就确定下来,不能直接引用常量池中的"helloworld"对象,而是在堆内存中创建一个新的String对象并由s4指向 42 * 所以s1==s4为false 43 * 44 */ 45 void test4() { 46 String s1="helloworld"; 47 String s2="hello"; 48 String s3="world"; 49 String s4=s2+s3; 50 System.out.println(s1==s4); 51 } 52 53 /** s2与s3被final修饰为宏变量,不可更改,编译器在程序使用该变量的地方直接使用该变量的值进行替代,所以s4的值在编译的时候就为"helloworld" 54 * 指向常量池中的"helloworld"对象 55 * 所以s1==s4为true 56 * 57 */ 58 void test5() { 59 String s1="helloworld"; 60 final String s2="hello"; 61 final String s3="world"; 62 String s4=s2+s3; 63 System.out.println(s1==s4); 64 } 65 public static void main(String[] args) { 66 Main o = new Main(); 67 o.test1(); 68 o.test2(); 69 o.test3(); 70 o.test4(); 71 o.test5(); 72 73 } 74 }