字符串不变性和常量值

来源:互联网 发布:微擎源码破解版 编辑:程序博客网 时间:2024/05/01 13:10

返回导航

1、判断一个字符串是否为空

if ( s == null ) //从引用的角度
if ( s.length() == 0 ) //从长度判别
if ( s.trim().length () == 0 ) //是否有多个空白字符
if (s!=null && s.length()!=0{
}


2、空串与null的区别?

它们是不同的概念。对未初始化的对象操作会被编译器挡在门外;
null是一个特殊的初始化值,是一个不指向任何对象的引用,
对引用为null的对象操作会在运行时抛出异常NullPointerException;
而空串是长度为0的字符串,和别的字符串的唯一区别就是长度为0

public class StringTest{
   static String s1;
   public static void main(String[] args) {
   String s2;
   String s3 = "";
   System.out.print(s1.isEmpty()); //运行时异常
   System.out.print(s2.isEmpty()); //编译出错
   System.out.print(s3.isEmpty()); //ok!输出true
  }
}


3、字符串的比较


Java不允许自定义操作符重载,因此字符串的比较要用compareTo() 或者 compareToIgnoreCase()。s1.compareTo(s2),返回值大于0则,
则前者大;等于0,一般大;小于0,后者大。比较的依据是字符串中各个字符的Unicode值。


4、字符串的不变性


String对象是不变的!可以变化的是String对象的引用

String name = "ray"; name.concat("long"); //字符串连接
System.out.println(name); //输出name,ok,还是"ray"
name = name.concat("long"); //把字符串对象连接的结果赋给了name引用
System.out.println(name); //输出name,oh!,变成了"raylong"
上述三条语句其实产生了3个String对象,"ray","long","raylong"。第2条语句确实产生了"raylong"字符串,
但是没有指定把该字符串的引用赋给谁,因此没有改变name引用。第3条语句根据不变性,
并没有改变"ray",JVM创建了一个新的对象,把"ray","long"的连接赋给了name引用,
因此引用变了,但是原对象没变。


5、String常量池

String的不变性的机制显然会在String常量内有大量的冗余。如:"1"+"2" + "3" +......+ "n" 产生了n+(n+1)个String对象!因此Java为了更有效地使用内存,JVM留出一块特殊的内存区域,被称为“String常量池”。
譬如String a = "abc"; 当你定义这样一个变量的时候,java此时先会去常量池寻找有没有"abc"这样的字符串,如果有,
直接把内存地址交给a, 否则就生成一个"abc"的字符串当下一个String b = "abc";的时候,发现常量池已经有"abc"了,
此时JVM不会再次生成"abc",而是直接交给"abc"引用给b, 所以此时你会发现a == b
思考以下输出:
//demo1:
String str1 = "java";
String str2 = "java";
System.out.print(str1==str2); //(true or false?)
//demo2:
String str1 = new String("java");
String str2 = new String("java");
System.out.print(str1==str2);   //(true or false?)
//demo3:
String str1 = "java";
String str2 = "blog";
String s = str1+str2;
System.out.print(s=="javablog");// (true or false?)
//demo4:
String s = "java"+"blog";
System.out.print(s=="javablog"); //(true or false)
//demo5:
String str2 = "blog";
String s = "java"+str2;
System.out.print(s=="javablog"); //(true or false)


6、字符串不变性的解决方案


StringBuffer

StringBuffer类是可变的,不会在字符串常量池中,而是在堆中,不会留下一大堆无用的对象。而且它可将字符串缓冲区安全地用于多个线程。
每个StringBuffer对象都有一定的容量。只要StringBuffer对象所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。
如果内部缓冲区溢出,则此容量自动增大。这个固定的容量是16个字符。我给这种算法起个名字叫“添饭算法”。
先给你一满碗饭,不够了再给你一满碗饭。


StringBuilder

从J2SE 5.0 提供了StringBuilder类,它和StringBuffer类是孪生兄弟,很像。它存在的价值在于:
对字符串操作的效率更高。不足的是线程安全无法保证,不保证同步。

0 0
原创粉丝点击