标签:
Java字符串的维护就是一个享元模式的具体体现,我们知道String的实例有两种方式分别是:
String str = "hello world"; String str2 = new String("hello world");
其中前者字面量的方式具体流程是这样的:首先查找 String Pool(栈)中是否有“hello world”,如果不存在,那会在String Pool中创建一个“hello world”,同时将这个对象的引用返回给str;如果String Pool中存在,那么直接获取String Pool中的值返回;
后者new一个的对象的具体流程是这样的:首先查找 String Pool中是否有“hello world”,如果不存在,那么同样在String Pool中创建一个,然后去堆(Heap)中创建一个“hello world”对象,并且把堆中的引用返回给str2;如果String Pool中存在了这个对象,那么,跳过String Pool中创建,而是直接在堆中去创建一个“hello world”然后把引用返回。
通过以上就会明白:
为什么
"hello world" == "hello world" 为 true ;
但是
new String("hello world") == new String("hello wrold") 为 false;
同时
"hello world" == new String("hello world") 也为false;
另外,String Pool 就是一个字符串的享元工厂,字面量的方式就是一个享元工厂模式。大家都知道StringBuffer的性能要好过 String,StringBuilder的性能要好过StringBuffer,可是为什么还要用String呢?原因就在这里,他们说的性能是字符串 修改的时候,而真正字符的基本操作,以及字符串从系统中获取的时候,String是最快的,维护的对象也最少。
String 重写了equals方法,Object的equals方法是直接比较两个对象的地址,所以使用在字符串上比较意义不是很大,想要判断两个字符串的是否相同,我们应该这样判断,采用重写的equals方法。具体代码如下:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
1)、字符串没有属性暴露,内部有属性一般是私有而且final类型的;比如offset、count、value;
2)、字符串重写了equals方法,那么也一定后重写了hashcode方法;
3)、字符串不能被继承是因为他是一个final类型的类;
4)、字符串内容不能更改是因为内部使用一个final类型的char数组存储,所以不能改变;
5)、字符串的优势在于他的速度,因为他的设计是一种享元设计模式。
标签:
原文地址:http://my.oschina.net/heweipo/blog/491088