String简介
String是java中很常用的字符串类型。作为八大基本数据类型之外的字符串数据类型,与基本数据类型不同的是,String是引用类型,也就是与我们自己定义的javaBean一样,需要通过new实例化的,只不过jdk给我们做了特殊的处理,直接使用类似于基本数据类型的方式初始化就可以使用。
1.String的初始化
其实字符串的初始化从源码来看是将获取到的字符串值转换成了一个字符数组存储在内存中的。
/** The value is used for character storage. */
private final char value[];
/**
* Initializes a newly created {@code String} object so that it represents
* an empty character sequence. Note that use of this constructor is
* unnecessary since Strings are immutable.
*/
public String() {
this.value = "".value;
}
这也就解释了字符串类型的变量为什么是不可变的。但是可能有人就问了,那为什么定义一个字符串变量之后还可能改变它的值呢?其实这时修改的不是字符串变量的值。众所周知,字符串初始化时是在内存中开辟出一个字符串存储在常量池,在栈中记录了它的引用指向变量名,也就是常量池的“test”字符串只是指向了变量str的。
当str变量被重新赋值使,会在内存重新开辟一个“param”然后指向str中,这时候之前的“test”失去str的指向,并没有被改变。
String str = "test";
str = "param";
2.常用方法
以下是开发过程string类常用的方法:
方法名 | 说明 | 备注 |
---|---|---|
int length() | 获取当前字符串长度 | 返回字符数组的长度 |
boolean isEmpty() | 判断字符串是否为空 | 判断数组长度是否为0 |
char charAt(int index) | 获取指定位置字符 | 返回指定索引的数组字符 |
byte[] getBytes() | 当前字符串转换为字节数组 | 获取操作系统默认的编码格式字节数组 |
boolean equals(Object anObject) | 判断相等 | 先==判断,不等再转为字符数组逐字符对比 |
int compareTo(String anotherString) | 按字典顺序比较两个字符串 | - |
boolean startsWith(String prefix) | 判断字符串前缀 | - |
boolean endsWith(String suffix) | 判断字符串后缀 | - |
int hashCode() | 获取字符串的HashCode | hash未定义(默认为0)时以31为模计算hash值 |
int indexOf(String str) | 获取指定索引位置的字符 | - |
String substring(int beginIndex, int endIndex) | 获取指定开始结束索引的字符串 | - |
String replace(char oldChar, char newChar) | 用newChar替换掉字符串变量中的oldChar | - |
String[] split(String regex) | 按照指定格式切割字符串成字符串数组 | - |
String trim() | 字符串去掉空字符 | 去掉字符串中“ ”字符 |
String toString() | 转换为字符串 | - |
char[] toCharArray() | 转换为字符数组 | - |
static String format(String format, Object… args) | 按照指定格式格式化字符串 | 静态方法,可通过String.format(…)调用 |
static String valueOf(Object obj) | 获取字符串类型值 | 静态方法,object为null时返回“null”字符串 |
其中需要特别注意的是equals方法,它会先用“==”直接判断传递过来的参数与字符串值是否相等,若相等时直接返回true;否则会判断传递来的参数是否为string类型的数据,若不是直接返回false;否则会将要对比的字符串转换为字符数组,通过while循环依次递减比对字符是否相等,遇到有任何一个不相等直接返回false,直到全部都对比向等候返回true。
/**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
String实现了Serializable接口,所以String类型的变量会转换成一个字节序列,并能够以后将这个字节序列完全恢复为原来的对象,可序列化并且实现轻量级持久,通过序列化对象写入磁盘,然后在重新调用程序时恢复该对象,就能够实现持久性的效果。允许一个字符串变量在虚拟机之间传送并且支持字符串变量进行深层复制。
String 实现了CharSequence接口,也就是说String也是CharSequence类型。
这个借口只包括length(), charAt(int index), subSequence(int start, int end)这几个API接口。
除了String实现了CharSequence之外,StringBuffer和StringBuilder也实现了CharSequence接口和Serializable接口,也就是说String、StringBuffer以及StringBulider的底层变量值存储方式都是字符数组。