初始Java——认识String
String a = "abf";
String a = new String("abvc");
char[] array = {'a','b','c','d','e'};
String a = new String(array);
String str = new String(array,2,2);//offset,count
sout(str);
sout(str == str2);//错误,存的是地址,不是值


课堂代码举例str == str2
String str1 = "hello";
String str2 = new String("hello");//false,new了新的内存块
String str3 = "he"+new String("llo");//false,在+拼接过程中,也会创建一块新的内存块,str3直接指向这块新的内存块,并不分别存两块的地址,拿回栈拼接
String str4 = "he" + "llo";//常量在编译前就已经拼接好了(19:39可以反编译看一下),在常量池先进行拼接,再传值,也就是说常量池里已经有hello的话,拼完直接就是那个现成的hello,所以地址相同,==true
String str5 = "he";
String str6 = str5+"llo";//false,因为在str6的位置认为str5是个变量,所以重新创建了,而不能把str5当作一个常量
String str7 = new String("he");
String str8 = new String("llo");
String str9 = str7 + str8;//false, 7和8分别有自己的,但是str9朝阳重新创建了一个内存区域,上边分别7和8的地址(19:43)
遇到str == str2的问题:
new出来的一定重新开辟内存空间,意味着一个新的地址
例子2:
byte a = 10;
byte b = 20;
byte c = a+b;//报错,运算自动转换成int运算,byte的C不能接收int型
final byte a= 10;
final byte b= 20;
byte c = a+b;//可以通过,因为常量加完再给回来
例子3:
String str1 = "hello";
String str2 = str1;//可以看出来,2并不是指向1,而是指向1的对象hello
str1 = "world";
sout(str2);
//执行结果
hello
public class testString {
public static void change(String str,char[] array){
//传值过来,在栈中又创建了一个Str,存着真正的str的地址
str = "haha";//给覆盖了新地址,但是没传回去
//只改变了形式参数,并不会影响到实参
array[0]= 'g';//数组操作是直接在数组上覆盖【0】位置直接给他盖了
}
public static void main(String[] args) {
String str = "hello";
char[] array = {'a','b','c'};
change(str,array);
System.out.println(str);
System.out.println(Arrays.toString(array));
}
}
//执行结果
hello
gbc
常量池
常量池:
同样的字符串,只能存一个
如果有,那么返回现在的地址给引用
如果没有,则存放进去,并且返回地址给引用
所有的池的作用:都是用于节省资源的(共享)
用equals比较内容
主动与被动关系
String str = null;
sout(str.equals("abc"));//报错空指针
sout("abc".equlas(str));//正常运行
intern()方法(选择题)
入池方法,给对象丢进常量池
String str1 = "hello";
String str2 = new String("hello").intern();//调用了intern会直接把常量池的hello给str2,如果是原来没有的也会在常量池创建一个hello
sout(str1 == str2);//true
str1 = str1+"";
1.每次拼接会产生一个新的对象,不会在原有的基础上进行修改
2.value 的指向不能发生改变
想越过权限,直接修改常量池的值:
反射
PSVM
String str = "abc";
//反射
Class cl = String.class;
Field valueField = cl.getDeclaredField("value");//必须与属性字段一样,不能改变
valueField.setAccessible(true);
char[] value = (char[]) calueField.get(str);
value[0] = 'h';
sout(str);
StringBuffer 和 StringBuilder20:50


StringBuiler sb = new StringBuilder("hello");
StringBuilder sb2 = new StringBuilder(sb);//向上转型
String与StringBuilder与StringBuffer的区别
String str = "hello";
String str2 = "abc";
//String的拼接被优化为StringBuilder
String str3 = str + str2;
StringBuilder sb = new StringBuilder();
sb.append("ab");
sb.append("cd");
- String的拼接会产生新的对象,但是StringBuilder 和 StringBufer的append方法来进行拼接,返回的是当前对象
- String的拼接会被优化为StringBuilder
StringBuffer多用于多线程,StringBuilder多用于单线程,String多用于单线程(Buffer会有一个synchronized是用来保证线程安全的,相当于锁)- 两个B的方法相较于String会更多
String与StringBuilder与StringBuffer类型转化
String转别的不能直接转
String str1 = "abc";
StringBuilder a = new StringBuilder(str1);
或者
StringBuilder a = new StringBuilder();
sb.append(str1);
两个B转String用ToString
字符、字节与字符串21:20
str.length()//length函数
array.length//length属性
ASCⅡ表
@Deprete——>当前方法已经过时了

浙公网安备 33010602011771号