public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = -6849794470754667710L;
...
}
String s = "abc"
; 此"abc"储存在方法区常量池中String s =new String("abc")
; 创建了对象那么对象存储在堆中首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "hello" + "world";
String s4 = s1 +"world";
String s5 = s1 +s2;
String s6 = (s1+s2).intern();
System.out.println(s3 == s4);//false
System.out.println(s3 == s5);//false
System.out.println(s3 == s6);//true
System.out.println(s4 == s6);//false
System.out.println(s4 == s5);//false
System.out.println(s5 ==s6);//false
}
//加号左右两边只要一个为变量,生成的结果就在堆中.
避免内存浪费:因为String的不可变性
输出下列代码结果:
public class MyString {
String str = new String ("good");
char [] ch ={‘t‘,‘e‘,‘s‘,‘t‘};
public void change(String str,char ch[]){
str="test ok";
// this.str = "test ok";
ch[0] =‘b‘;
}
public static void main(String[] args) {
MyString s = new MyString();
s.change(s.str,s.ch);
System.out.print(s.str + " and ");
System.out.println(s.ch);
}
}
"good and best"
why :
解释: change(String str,char ch[]), str, ch在chang里都是引用类型, 为什么ch经过change方法后发生改变,而str却没有呢.
主要原因是因为字符串的不可变性, str="test ok",为字面量赋值,在常量池创建了新的常量,也生成了新的地址,str指向了新地址, 对象的this.str 的内容并未被修改. str.replace() 操作返回的也是新对象. 而this.str = "test ok" ,则是改变了对象属性的引用地址.
String s = new String("xyz");创建了几个String Object:
? 两个,一个字符对象,一个字符对象引用对象
可变的字符串容器,append可添加多种类型
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
/*
StringBuffer(),初始容量为16字符串cache
*/
public StringBuffer() {
super(16);
}
/*
StringBuffer(int size) : 构造指定容量的字符串缓冲区
*/
public StringBuffer(int capacity) {
super(capacity);
}
/*
super(str.length()+16)、append(str),这也就很清楚的说明了 StringBuffer 的创建过程,先创建一个长度为"str 长度+16"的字符串缓冲区,然后把 str 的值追加到此字符串序列中
*/
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
/*
线程安全,但方法同步需要消耗一定的系统资源
StringBuilder 虽然线程不安全,但是效率高
*/
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
}
//StringBuffer父类
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
/*
char [] value ; 没有声明为final,可扩容
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
方法链
//
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
count += len;
return this;
}
//返回当前对象 再执行方法
1、StringBuilder 的效率一定比 String 更高吗?
? 不一定;
String str = "Hello"+"World";//"Hello"+"World" 在编译期间会自动优化为 "HelloWorld"
StringBuilder stringBuilder = new StringBuilder("Hello");
stringBuilder.append("World");
原文:https://www.cnblogs.com/starry7/p/14311175.html