标签:
下面的代码是一个String对象的两种不同的初始化方式,关于这两种不同初始化方式的区别,本文通过画内存图来进行解释,首先代码如下:
public class Test { public static void main(String[] args) { String s1 = new String("hello"); String s2 = "hello"; System.out.println(s1 == s2); System.out.println(s1.equals(s2)); } }
s1是通过String类的构造方法进行初始化的,s2是通过字符串常量进行赋值初始化的,该程序在内存中的图如下:
字符串常量都是存储在方法区的字符串常量池中,所以第一种方式的初始化是先在堆中建立一个对象,然后该对象的值来自方法区的“hello”,所以方式1的初始化方式最多会创建2个对象,最少创建1个;方式2的初始化由于是字符串常量直接赋值,所以直接去方法区里面查找,最后返回已有对象,所以方式2的初始化方式最多创建1个对象,最少创建0个,例如本例中,由于方法区中已有“hello”,所以创建0个。
直接上代码来解释了:
public class Test { public static void main(String[] args) { String s = "hello"; String s1 = s; System.out.println("s: " + s); System.out.println("s1: " + s1); System.out.println("---------------"); s = "world"; System.out.println("s: " + s); System.out.println("s1: " + s1); } }
结果:
s: hello s1: hello --------------- s: world s1: hello Process finished with exit code 0
可以看出,对s进行重新复制,并没有改变原来的hello,只是将s指向了新的“world”。
首先看下面这段代码中的helloworld的不同拼接方式:
public class Test { public static void main(String[] args) { String s1 = "hello"; String s2 = "world"; String s3 = "helloworld"; System.out.println(s3 == s1 + s2); System.out.println(s3.equals(s1 + s2)); System.out.println("-------------------"); System.out.println(s3 == "hello" + "world"); System.out.println(s3.equals("hello" + "world")); } }
程序运行的结果是:
false true ------------------- true true Process finished with exit code 0
equals的比较由于内容相同,为true并不奇怪,但是变量拼接和s3比较的结果为false,而常量拼接结果却为true。这就是String中常量拼接和变量拼接的区别了。
System.out.println(s3 == (new StringBuffer(String.valueOf(s1)).append(String.valueOf(s2))).toString());
System.out.println(s3 == "helloworld");//所以可以看出,编译器对变量的拼接直接做了优化
标签:
原文地址:http://www.cnblogs.com/gslyyq/p/4928837.html