String字符串
String很重要哦
-
new String("Hello")(new就已经在堆上创建一个对象了,之后视运行情况而定,如果常量池中有"Hello",就不再在常量池中创建一个"Hello",直接把常量池中的"Hello"引用给堆的对象的变量,
String str1 = new String("a") 和 String str2 = new String("a") ==判断不同是因为str1于str2在堆中的引用对象不同
如果常量池没有"Hello",会先在常量池创建一个"Hello",再将引用给堆的对象封装,)
-
通过字面量赋值创建字符串(
String str = "hello")会先在常量池中查找是否存在相同的字符串,若存在,则将栈中的引用直接指向该字符串;若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。
-
常量字符串的 “+” 操作,编译阶段直接会合成为一个字符串
-
常量字符串和变量拼接时,会调用stringBuilder.append()在堆上创建新的对象。
定义和设置 一个字符串
/* java中所有使用""括起来的字符串都会在“字符串常量池”中创建一份。
字符串常量池在方法区中被储存
当代码中出现""形式创建字符串对象时,JVM首先会对这个字面量进行检查,
如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,
否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。
*/
注意:使用String时我们应该注意的问题:尽量不要频繁的做字符串的拼接操作, 字符串一旦创建不可改变,只要频繁创建就会在字符串常量池中创建大量的 字符串对象,给垃圾回收带来问题。
String类源码
public final class String
//final 关键字 final修饰类,该类无法被继承
implements java.io.Serializable, Comparable<String>, CharSequence{
//实现 序列化接口 比较器接口 字符序列接口
/* 一个类的属性,说明String里面装字符的就是一个char类型的数组
final修饰在这是指明 关键-> 引用不可变 即 字符串不可变 */
private final char value[];
/* 这种是 无参构造 通过 new 关键字 new String() 就是调用这
创建了一个字符串为 "" (空)的 对象(不知道以后在了解,只要知道是 new出来的) */
public String() { this.value = "".value; }
/* 一般赋值没必要这样 new String("没必要"),
就把已有的String传给另一个新的对象(具体关系看下面 String不可变与改变) */
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
// 将一个char类型数组转为字符串
public String(char value[]) {
//这个Arrays.copyOf 又是调的 Arrays类的一个静态方法(暂了)
this.value = Arrays.copyOf(value, value.length);
}
// 将一个char类型数组转为字符串 从数组里的那个下标到另一个下标
public String(char value[], int offset, int count) {
//...
}
// 将一个int类型数组转为字符串 方法重载(了解方法重chong载)
public String(int[] codePoints, int offset, int count) {}
// 将一个StringBuffer类转为字符串
public String(StringBuffer buffer) {
synchronized(buffer) {
this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}
}
//还有许多方法和构造 省了,暂时不了解太多
}
String的方法
equals
判断两个字符是否相等(用户的密码和登录输入密码判断相等时),基本全部用equals进行比较,不要用==
== 对于8个基本来说 比较数据的是值是否相等
== 对于引用类型来说 比较的是两个对象的引用地址是否相等
(java中所有使用""括起来的字符串都会在 “字符串常量池”中创建一份。字符串常量池在方法区中被储存当代码中出现""形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。)
equals 在String中其实是重写了所有类的父类Object中equals方法


String的equals顺序判断是这样的
this == anObject:若当前对象和比较的对象是同一个对象,即return true。也就是Object中的equals方法。anObject instanceof String:若当前传入的对象是String类型,继续判断,不是不进if{}中执行语句,然后 返回falsereturn false;n== valuse.length; if(n == anotherString.value.length)则比较两个字符串的长度,相同继续判断,不同不进if{}中执行语句,然后 返回falsereturn false;- 若长度相同,则按照数组value中的每一位进行比较,不同,则返回false。若每一位都相同,则返回true。不同直接进入if{}执行
return false;
length
获取到字符串的长度
charAt
前面我们知道String就是一个不可变的char数组,所以也可以根据下边取字符中下标为几的char字符
注意:下标一定要在取得字符串[0,length) 下标0开始到下标(字符串的长度-1)最后一个字符 中
getBytes
获取字符串的字节序列(即存储的字节数组) 字符串的byts数组
compareTo
按字典顺序比较两个字符串是否相等。
compareToIgnoreCase也是比较顺序,其他一样,区别是 compareToIgnoreCase忽略大小写比较
indexof
返回第一次出现的指定字符在此字符串内的索引,从指定的索引开始搜索。
源码中 public int indexOf(int ch) {}传入参数是int,
所以其实str.indexOf(98)和str.indexOf('b')是一样的因为b字符的ASCII码就是98
解释:在对字符型数据进行相加减运算的时候,系统会首先将char型数据以隐形的方式转化为int型数据再进行相加减运算。因此,由字符型数据在内存的存储方式来看,字符型数据在做数字运算时实际上是对字符本身对应的ASCII码进行相应的数值运算。
整型和字符型可以相互转换:
(char) 整型变量 = 字符型变量
(int) 字符型变量 = 整型变量
lastIndexOf
返回最后一次出现的指定字符在此字符串内的索引。
(和indexOf一样,只不过是从后向前,也可以指定从哪个下标从后向前开始)
substring
返回一个字符串,该字符串是该字符串的子字符串。(截取字符串的一部分)
replace
返回替换所有出现的字符串的新字符串(替换)
split
围绕给定的匹配项拆分此字符串(分割),此方法返回的数组包含此字符串的每个子字符串,
注意: . 、 $、 | 和 * 等转义字符,必须得加 \\
public String[] split(String regex, int limit) {}
再加一个limit(分割的份数)
toLowerCase
使用默认语言环境的规则将此字符串中的所有字符转换为小写
toUpperCase
使用默认语言环境的规则将此字符串中的所有字符转换为大写
也可以自定义规则(没试过.....)
toCharArray
将此字符串转换为新的字符数组
format
使用指定的格式字符串和参数返回格式化的字符串。
https://www.cnblogs.com/wqbin/p/11234659.html
(不熟,写了自己也记不住只有几个用得熟,记好位置,以后用得到的时候看就好了)
valueOf
返回 将传入数据类型的参数转换为String后 的字符串
基本数据类型、char数组(数组中从哪个下标到那个下标)和Object(所有类都默认继承了Object)(关于重写toString)
intern
当调用 intern() 方法时,查看常量池中是否有该字符串,有就直接返回常量池中指向该常量的引用,没有的话,编译器会将字符串添加到常量池中,并返回指向该常量的引用。
分析:
-
str 在堆中创建一个字符串对象并指向其位置
-
s1 在常量池中生成一个"str"的字符串
-
s2 在堆中创建一个字符串对象并指向其位置
-
str指向堆中的对象 s1.intern指向的常量池中"str" false
-
str指向堆中的对象 s2.intern指向的常量池中"str" false
-
s1 指向的常量池中"str" s2.intern指向的常量池中"str"也是 true


浙公网安备 33010602011771号