String是常量,在定义之后不能被改变,字符串缓冲区支持可变的字符串。因为String对象是不可变的,所以可以共享。
定义
public final class String implements java.io.Serializable, Comparable, CharSequence{}
String 是final类型,表示该类不能继承,同时实现了三个接口java.io.Serializable
, Comparable<String>
, CharSequence
。
属性
private final char value[];
final类型的字符数组,用来存储字符串的内容,因为被final修饰,所以String一旦初始化之后是不能被更改的。
private int hash;
缓存的hashCode值,默认为0。
private static final long serialVersionUID = -6849794470754667710L; private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];
String实现了Serializable
接口,所以支持序列化和反序列化。
java 的序列化机制是通过在运行时判断类的
serialVersionUID
来验证版本一致性。在进行反序列化时,JVM会把传过来的字节流中的serialVersionUID
与本地响应实体的serialVersionUID
进行比较,如果相同就认为是一致的,可以进行反序列化,否则就抛出版本不一致的异常(InvalidCastException
)。
构造方法
- 使用字符数组
当使用字符串数组创建的时候,会用的Arrays.copyOf
方法和Arrays.copyOfRange
方法。将源字符数组数据一一复制到String中的字符数组中。
//offset为起始位置,count为数量 public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count <= 0) { if (count < 0) { throw new StringIndexOutOfBoundsException(count); } if (offset <= value.length) { this.value = "".value; return; } } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count); }
- 字符串构造
使用字符串创建时,会将源String中的value
和hash
两个属性直接赋值给目标String。
public String(String original) { this.value = original.value; this.hash = original.hash; }
- 字节数组构造
char[]
字符数组是以unicode码来存储的,String
和char
为内存形式,byte
是网络传输或存储的序列化形式。可以通过charset来解码指定的byte数组,将其解码成unicode的char[]数组,构造String。
String(byte bytes[]) String(byte bytes[], int offset, int length)String(byte bytes[], Charset charset)String(byte bytes[], String charsetName)String(byte bytes[], int offset, int length, Charset charset)String(byte bytes[], int offset, int length, String charsetName)
- 使用
Stringbuider
和StringBuffer
构造虽然存在当前的构造方式,但是和toString()
方法相比,效率比较低。所以可以直接使用toString()
代替。
public String(StringBuffer buffer) { synchronized(buffer) { this.value = Arrays.copyOf(buffer.getValue(), buffer.length()); } } public String(StringBuilder builder) { this.value = Arrays.copyOf(builder.getValue(), builder.length()); }
其他方法
getBytes
String s = "你好,世界!"; byte[] bytes = s.getBytes();
这段代码在不同的平台上运行得到结果是不一样的。由于没有指定编码方式,所以在该方法对字符串进行编码的时候就会使用系统的默认编码方式,比如在中文操作系统中可能会使用GBK或者GB2312进行编码,在英文操作系统中有可能使用iso-8859-1进行编码。这样写出来的代码就和机器环境有很强的关联性了,所以,为了避免不必要的麻烦,我们要指定编码方式。如使用以下方式:
比较方法
boolean equals(Object anObject);boolean contentEquals(StringBuffer sb);boolean contentEquals(CharSequence cs);boolean equalsIgnoreCase(String anotherString); //使用toUpperCase方法转换成大写,在进行比较int compareTo(String anotherString);int compareToIgnoreCase(String str);boolean regionMatches(int toffset, String other, int ooffset,int len); //局部匹配boolean regionMatches(boolean ignoreCase, int toffset,String other, int ooffset, int len); //局部匹配
String s = "你好,世界!"; byte[] bytes = s.getBytes("utf-8");
其他
ength(); //返回字符串长度isEmpty(); //返回字符串是否为空charAt(int index;) //返回字符串中第(index+1)个字符char[] toCharArray(); //转化成字符数组trim();// 去掉两端空格toUpperCase();// 转化为大写toLowerCase();// 转化为小写String concat(String str); //拼接字符串String replace(char oldChar, char newChar); //将字符串中的oldChar字符换成newChar字符//以上两个方法都使用了String(char[] value, boolean share);boolean matches(String regex); //判断字符串是否匹配给定的regex正则表达式boolean contains(CharSequence s); //判断字符串是否包含字符序列sString[] split(String regex, int limit;) //按照字符regex将字符串分成limit份。String[] split(String regex);