zoukankan      html  css  js  c++  java
  • String的花式比较

    首先了解字符串常量池的设计思想:

    字符串的分配和其他的对象分配一样,需要耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串会极大程度地影响程序的性能。JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化:

    1)为字符串开辟一个字符串常量池,类似于缓存区。

    2)创建字符串常量时,首先坚持字符串常量池是否存在该字符串。

    3)存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中。

    实现的基础:

    1)实现该优化的基础是因为字符串是不可变的,可以不用担心数据冲突进行共享。

    2)运行时实例创建的全局字符串常量池中有一个表,总是为池中每个唯一的字符串对象维护一个引用,这就意味着它们一直引用着字符串常量池中的对象,所以,在常量池中的这些字符串不会被垃圾收集器回收。

    在创建字符串的时候,通过直接赋值(String a="a")创建的对象是保存在常量池中,通过String a=new String("a")创建的对象是保存在堆内存中,主要是返回指向对象的句柄的不同(具体可以查询句柄、引用、对象的关系)

    除此之外在new String(XXX)在创建的时候过程会存在这样的情况,如果XXX不存在在常量池中,则创建XXX保存在常量池,这样就生成两个对象,一个在堆,一个在常量池

    但是存在以下情况String c=new String("a")+new String("b"),在常量池中是不存在“ab”这么个对象的,在这里可以使用c.intern()将c对象保存到常量池中去。

    回到正题了,下面是一些字符串比较的例子和说明:

     1 public void StringTest(){
     2 
     3         //编译期可确定值的常量就是编译期常量,即被final修饰的字符串变量,final String a = "12",a也是编译器常量。String b = "34",因为不是final的所以不是编译期常量。
     4         //字符串属于引用数据类型。对于引用类型,==是地址值的比较

    //主要是编译器是否对语句进行优化 5 6 String s1="1234"; 7 //对于两个编译期常量字符串相加,编译器会进行优化,直接优化成"1234",所以不会在字符串常量池中创建"12","34"这两个字符串对象,而只会创建一个"1234"字符串对象。 8 String s2="12"+"34"; 9 System.out.println(s1==s2); 10 11 //对象保存在堆内存中,所以肯定不相等 12 String s3=new String("1234"); 13 System.out.println(s1==s3); 14 15 //s4+"34"在运行期,相加的结果是生成一个新的字符串对象放置在堆内存中 16 String s4="12"; 17 String s5=s4+"34"; 18 System.out.println(s1==s5); 19 20 //引用不变,但是还是指向了在堆内存中的字符串对象 21 String s6="12"; 22 s6+="34"; 23 System.out.println(s1==s6); 24 25 //substring和replace出来的都是新的字符串,即使常量池中存在截取后的或者替换后的字符串,==也不相等。 26 String s7="123456".substring(0,4); 27 System.out.println(s1==s7); 28 29 //堆对象+创建的对象依然是堆对象 30 String s8="12"; 31 String s9="34"; 32 String s10=s8+s9; 33 System.out.println(s1==s10); 34 35 //s11被修饰成编译期常量了,相当于s12=“12”+“34”,会被编译器优化 36 final String s11="12"; 37 String s12=s11+"34"; 38 System.out.println(s1==s12); 39 40 //这种方式还是创建成堆对象 41 String s13=new String("12"); 42 String s14=s13+"34"; 43 System.out.println(s14==s1); 44 45 46 //这是intern作用的例子,堆对象调用inter会将自身放到字符常量中 47 String b=new String("9")+new String("9"); 48 b.intern(); 49 String a="99"; 50 System.out.println(a==b); 51 52 String c=new String("19")+new String("19"); 53 String d="99"; 54 System.out.println(c==d); 55 56 }
     
  • 相关阅读:
    Silverlight开发“慢”游美丽的分形世界(画分形2)
    c#进阶methods中3explicit和implicit
    C#进阶可选参数和命名参数
    Silverlight杂记自定义loading
    c#进阶params可变个数的参数
    Abundant Resources
    欧拉函数
    容斥原理 讲解
    sdut 2497 A simple problem (并查集 or dfs)
    hdu 4366 Card Collector (容斥原理)
  • 原文地址:https://www.cnblogs.com/qizhufeitian/p/14045605.html
Copyright © 2011-2022 走看看