Java小细节(二)

java小细节(二)(字符串相关)

这次的内容主要是与字符串相关。

字节

字节是计算机存储信息的基本单位,1 个字节等于 8 位, gbk 编码中 1 个汉字字符存储需要 2 个字节,1 个英文字符存储需要 1 个字节。所以我们看到上面的程序运行结果中,每个汉字对应两个字节值。同时,汉字对应的字节值为负数,原因在于每个字节是 8 位,最大值不能超过 127,而汉字转换为字节后超过 127,如果超过就会溢出,以负数的形式显示。

字符串不可变

String 对象创建后则不能被修改,是不可变的,所谓的修改其实是创建了新的对象,所指向的内存空间不同。
一旦一个字符串在内存中创建,则这个字符串将不可改变。如果需要一个可以改变的字符串,我们可以使用StringBuffer或者StringBuilder

补充一点String的用法

Java小细节(二)
例如
split()方法:
String N_K = in.nextLine();
String list[] = N_K.split(“r”);//将这个输入的String以“r”分开
注意:
1、如果用“.”作为分隔的话,必须是String.split("\."),这样才能正确的分隔开,不能用String.split(".");
2、如果用“|”作为分隔的话,必须是String.split("\|"),这样才能正确的分隔开,不能用String.split("|");
“.”和“|”都是转义字符,必须得加"\";
3、如果在一个字符串中有多个分隔符,可以用“|”作为连字符,比如,“acount=? and uu =? or n=?”,把三个都分隔出来,可以用String.split(“and|or”);

还有关于StringBuilder

Java小细节(二)
String和StringBuffer(线程安全)、StringBuilder(线程不安全)之间的转换:
1、String→StringBufferr:
    方法一:通过StringBuffer构造方法:StringBuffer sb=new StringBuffer(str);
    
    方法二:通过append()方法:
        String str;
        StringBuffer sb=new StringBuffer();
        sb.append(str);
2、StringBuffer→String:
    方法一: StringBuffer sb=new StringBuffer(“abs”);
         String str=new String(sb);
    方法二: StringBuffer sb=new StringBuffer(“abs”);
         String str=sb.toString();

StringBuilder转换情况类比StringBuffer

注意

String a1=“山东大学”;
String a2=“山东大学”;
System.out.print(a1==a2);
//结果为true
//"山东大学"为常量字符串,多次出现时会被编译器优化,只创建一个对象

String a=“a”;
String c=a;
System.out.println(a==c);
//true
// 他们都是在常量池中,引用指向同一个地址

String a3=a1+“牛逼”;
String a4=a1+“牛逼”;
System.out.print(a3==a4);
//结果为false
// a1是变量,a4在运行时才知道具体值,所以a3和a4是不同的对象

String a=“a”;
String b=“b”;
String c=“a”+“b”;
System.out.println(a+b==c);
System.out.println(“ab”==c);
//false true
第四行的执行如下:
a+b: new StringBuffer(“a”).append(“b”).toString();即在堆中新创建了一个对象,两者不再是同一个对象

但是编译器做了一些优化,在编译时期,String c=“a”+"b"的编译结果是String c=“ab”.

进行引用传递时,对原对象的引用是不会改变的。
就是说可以进行append(1)来添加字符,但是不能将另一个值赋过去。

实际上,java的参数传递只有值传递!但是便于理解,我们根据参数类型的不同分为值传递和引用传递,其中对于基本数据类型和不可变对象(包装类和String类)采取的是值传递,对于其他的引用类采取的是引用传递,引用传递可以在方法中修改原对象的内容,但是对原对象的引用始终不会改变!

感谢阅读!