• java中的String类的一点认识


    这是学习中用到的一些基础知识

    String 是经常会用到的一个类,学习的过程中发现的东西进行的汇总。

    1. 初始化方面:

      String类是一个比较特别的类,初始化的时候有种简化的特殊语法。

      1>String s = "abc";

      而按照正规的语法来说,应该是:

      2>String s = new String ("abc");

      建议使用1>的方式,原因在于这样比较节省内存空间,从其他网站上照抄下来的说法是,【只是按照面向对象的标准语法,在内存使用上存在比较大的浪费。例如         String s = new String(“abc”);实际上创建了两个String对象,一个是”abc”对象,存储在常量空间中,一个是使用new关键字为对象s申请的空间。】

      下面是简单的代码

      

    1         String a = "abc";
    2         String b = "abc";
    3         System.out.println(a==b);

      打印的结果是True。这里的代码含义在于,创建了String类型的引用变量,a和b,a和b指向了值为"abc"的String类,至于是不是新建的String类型的对象,需要根据代码的前后文进行分析(因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象)。结果为True,代表这至少第二行代码没有重新创建一个String类型的对象,而是指向了存在的"abc"的对象,所以a 和 b 指向的是同一个对象,必然两者是相等的。

      再如下面的代码:

    1         String d = new String("abc");
    2         String e = new String("abc");
    3         System.out.println(d==e);

      打印的结果是False,即 d, e两个String类型的引用是指向不同的对象,1,2行代码的处理逻辑是: 不管其字符串值是否相等,是否有必要创建新对象,都会创建新的对象。

      另外研究到这里的时候,发现代码1中,提出了一个设计模式的思想-享元模式,即复用内存中已经存在的对象,降低系统创建对象实例的性能消耗。至于更多的分析可能会随着学习逐步的深入

    2. String的只读特性

      String是一个常量,在初始化的时候,一旦创建就不能再被改变,所以看起来是修改了String值的方法,其内部的逻辑并非如此。如下面的代码:

      

    1 String a1 = "first";
    2 System.out.println(a1 + ", second");

      打印之后是“first, second”,其实内部逻辑上来看,其实是生成了一个新的String对象,而不是在原有的String对象上追加内容。

      而java的内部处理方式上有说法是通过StringBuilder 这个类来实现字符串的拼接。所以大胆假设下,以上的代码等同于如下的实现方式:

    1 StringBuilder stringBuilder = new StringBuilder();
    2 stringBuilder.append(a1);
    3 stringBuilder.append(", second");
    4 System.out.println(stringBuilder.tostring());

      通过上面的代码可以看出,如果假设是成立的情况下,在进行字符串拼接的时候如果使用的“String + ”的方式进行的,而在java内部是通过StringBuilder的方式来实现的话,那会创建一个StringBuilder对象来处理,单个的情况下不会有太多额外消耗,但是如果在循环体中使用了“String +”的方式,会不断进入循环的时候不端创建StringBuilder对象,这样反倒是有增加内存开支的嫌疑。所以如果以上假设都成立的话,在使用到字符串拼接的时候,干脆使用StringBuilder 的方式不是更好么?省的转换成StringBuilder的方式后还得在每次循环中不断的创建StringBuilder对象。

    3. equals 和 “==”的区别

    简单的说,String的 equals()方法比较字符串对象中的字符, == 运算符比较的是两个对象是否引用同一实例,代码如下:

    1         String s1 = "Hello";
    2         String s2 = new String(s1);
    3         System.out.println(s1.equals(s2)); //True 
    4         System.out.println(s1==s2); //False

    这个代码就比较简单了,看下面是equals的实现方法

    public boolean equals(Object anObject) {
        if (this == anObject) { //判断是否同一对象
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;//String类型
            int n = count;
            //一个字符一个字符的比较
            if (n == anotherString.count) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = offset;
            int j = anotherString.offset;
            while (n-- != 0) {
                if (v1[i++] != v2[j++])
                return false;
            }
            return true;
            }
        }
        return false;
        }    

    从源码中看到了两个事情:

    1. 如果equals对比的是两个对象的话,那equals 和  == 是同样的判断逻辑

    2. 只有当判断出都是String类型的对象的时候,才会去对比每个字符是否相等。

    看源码是个好习惯,要有耐心。

      

  • 相关阅读:
    docker usage (2)
    Linux command
    Postgresql 教程
    visual env VS conda environment of python
    Django教程(1)
    发生android.view.ViewRoot$CalledFromWrongThreadException异常的解决方案(转载http://daydayup1989.iteye.com/blog/784831)
    如何保留小数点后一位
    (四)详解android:scaleType属性
    (三)android布局基础及范例:人人android九宫格布局(转载http://blog.csdn.net/jiabinjlu/article/details/6921008)
    (二)android中在xml文件中使用View在某个控件的上方画一条线;android:listSelector的属性说明;android:visibility="gone"
  • 原文地址:https://www.cnblogs.com/kevinqinan/p/4481578.html
Copyright © 2020-2023  润新知