• Java常量字符串String理解 String理解


    以前关于String的理解仅限于三点:
    1、String 是final类,不可继承
    2、String 类比较字符串相等时时不能用“ == ”,只能用  "equals" 
    3、String  类不可更改

    String 使用非常方便,因此一般涉及字符串时都用该类进行字符串处理
    至于String类的类在机制,则极少去探究。

    直到读到下面这个例子。

    class X
    {  
       public static String strX="hello";
    }
    class Y
    {
       public static String strY="hello";
    }
    class Z
    {
       public static String strZ="hell"+"o";
    }
    class Test
    {
       public static void main(String[] args)
       {
            System.out.println( X.strX==Y.strY);  
            System.out.println( X.strX==Z.strZ);
            String s1="hel";
            String s2="lo";
            System.out.println( X.strX==(s1+s2));
            System.out.println( X.strX==(s1+s2).intern());
        }
    }



    按照我的理解,类X,类Y,类Z中的三个常量字符串属于不同的对象,用 == 操作符比较,那么结果必然是 false,输出应该为:
    false
    false
    false
    false

    但实际上输出确是:
    true
    true
    false
    true
    使我大惑不解。并因此找了许多资料来看(尤其是C++和Java比较编程,里面解释比较详细),终于逐渐明白了原因。

    == 只有在两个比较对象指向同一对象时,其值才为true。X.strX==Y.strY 与 X.strX==Z.strZ 测试结果都为true,说明这三个常量指向的都是同一个对象。
    在JAVA中,String 是字符串常量。由相同序列的字符组成的两个字符串属于同一对象,位于内存中的同一个位置。每个字符串常量只有一个 String 对象来表示。即使这个字符串常量出现在一个程序的不同位置甚至一个程序的不同程序包中。也就是说,X.strX 与 Y.strY 由于都是同一字符序列,因此 指向的肯定是同一对象。
    Z.strZ 也是如此。"hell"+"o",两个常量字符串相加后,创建了一个新的字符串常量(这个工作是编译期间完成的),它与 X.strX ,Y.strY有相同的字符序列,因此指向同一对象 。

    虽然一个常量表达式将两个字符串常量链接在一起的结果在编译器已完成,但是 
     String s1="hel";
     String s2="lo";
     String s3=s1+s2;
    这段代码中,s3只能在运行期间创建。这三条语句所创建的"hello"字符串作为String对象存储在内存中的一个独立位置。

    Java提供一个机制,通过String类定义的intern()方法把一个运行时创建的字符串加到字符串常量池(如果它还没有入池)。如果上面的三条代码改为:
     String s1="hel";
     String s2="lo";
     String s3=(s1+s2).intern();
    java将把 s1+s2 所返回的字符串对象中的字符序列与已经存储在字符串常量池中的字符串进行比较。如果找到一个匹配,intern()就返回这个字符串的引用。如果没有找到匹配,s1+s2 所返回的字符串将被加入到字符串常量池中,并返回这个字符串常量的引用。
    这就解释了为社么X.strX==(s1+s2)返回false,而X.strX==(s1+s2).intern()返回true。(s1+s2).intern()指向strX,strY,StrX指向的字符串常量"hello"。

    本人追加测试代码如下:

    /**
    *
    * @author ocq
    */
    public class testString{

    public static void main(String[] args) {

    String s1 = "a";
    String s2 = "b";
    String s3 = "ab";
    String s4 = s1 + s2;
    String s5 = "a" + "b";
    String s6 = s1 + "b";
    StringBuffer s7 = new StringBuffer("abc");
    String s8 = s7.substring(3);
    StringBuffer s9 = new StringBuffer("abc");

    System.out.println((s3 == s4));//false
    System.out.println(s3 == s5);//true
    System.out.println(s3 == s6);//false
    System.out.println(s4 == s6);//false
    System.out.println((s4 == s8));//false
    System.out.println((s7.toString() == s9.toString()));//false

    }
    }

    原文:http://blog.csdn.net/kofsky/article/details/1882626

  • 相关阅读:
    用最简单的例子理解装饰器模式(Decorator Pattern)
    用最简单的例子理解迭代器模式(Iterator Pattern)
    用最简单的例子理解观察者模式(Observer Pattern)
    用最简单的例子理解单例模式(Singleton Pattern)
    用最简单的例子理解对象为Null模式(Null Object Pattern)
    用最简单的例子理解策略模式(Strategy Pattern)
    使用Lazy<T>实现对客户订单的延迟加载
    C#关键字var是什么,在何种情况下使用
    C#中的IDisposable模式
    CLR基础,CLR运行过程,使用dos命令创建、编译、运行C#文件,查看IL代码
  • 原文地址:https://www.cnblogs.com/langtianya/p/3873150.html
Copyright © 2020-2023  润新知