栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

零基础java自学流程-Java语言进阶68

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

零基础java自学流程-Java语言进阶68

想要系统学习JAVA推荐JAVA300集
Java300集零基础适合初学者视频教程←点击

 

 

String、StringBuffer、StringBuilder

1.String STR ="hello world" and String STR =new String("hello world")

想必您熟悉上面的两条语句,在通常的代码编写过程中经常会遇到,那么它们之间有什么区别和联系呢?以下是一些例子:

public class Main {
         
    public static void main(String[] args) {
        String str1 = "hello world";
        String str2 = new String("hello world");
        String str3 = "hello world";
        String str4 = new String("hello world");
         
        System.out.println(str1==str2);
        System.out.println(str1==str3);
        System.out.println(str2==str4);
    }
}

  这段代码的输出结果为

  

 

为什么会发生这种情况?原因如下:

正如在之前关于JVM内存机制的文章中提到的,类文件中有一节存储在编译期间生成的文字常量和符号引用。这部分称为类文件常量池,它对应于方法区域的运行时常量池。

所以在上面的代码中,String str1 = "Hello world";str3 = "Hello world";文字常量和符号引用都是在编译时生成的,运行时文字常量“Hello World”存储在运行时常量池中(当然,只有一个副本)。要以这种方式将String绑定到引用,JVM执行引擎首先在运行时常量池中寻找相同的文字常量,如果是,则直接将引用指向已经存在的文字常量。否则,在运行时常量池中创建一个空间来存储文字常量并引用它。

如您所知,通过new关键字生成的对象是在堆中完成的,而堆中的对象生成并不检测对象是否已经存在。如果你用new创建一个对象,你会创建一个不同的对象,即使字符串的内容是相同的。

2. StringBuffer和StringBuilder之间的区别

为什么我们需要StringBuilder和StringBuffer类,当我们在Java中已经有了String类?

看看这段代码:

public class Main {
         
    public static void main(String[] args) {
        String string = "";
        for(int i=0;i<10000;i++){
            string += "hello";
        }
    }
}

这个字符串+= "hello";等价于在字符串中添加“Hello”并将其存储在一个新的字符串中,并使该字符串指向新生成的对象。如果你有任何问题,反编译它的字节码文件:

从这个反编译的字节码文件中可以清楚地看到,整个循环从第8行执行到第35行,每个循环创建一个New StringBuilder对象,添加它,并通过toString方法返回一个String。也就是说,在执行循环之后,已经创建了10,000个新对象。想象一下,如果没有收集这些对象,会浪费多少内存。string+="hello"操作实际上是由JVM自动优化的:

StringBuilder = new StringBuilder(string);

str.append(“hello”);

str.toString ();

看看下面的代码:

 

public class Main {
         
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        for(int i=0;i<10000;i++){
            stringBuilder.append("hello");
        }
    }
}

  反编译字节码文件得到:

 

从这里可以清楚地看到,代码的for循环从第13行开始,到第27行结束,而且新操作只完成一次,也就是说,只生成一个对象,而追加操作是在原始对象上完成的。因此,在10,000次循环之后,这段代码占用的资源要少得多。

有人可能会问为什么我们有一个StringBuilder类还需要一个StringBuffer类呢?如果查看源代码,可以看到StringBuilder和StringBuffer具有本质上相同的成员属性和方法。区别在于StringBuffer类的成员方法前面有一个关键字:Synchronized,不用说,是一个受多线程访问保护的关键字,这意味着StringBuffer是线程安全的。

下面的代码片段来自StringBuffer和StringBuilder。

StringBuilder的插入方法

public StringBuilder insert(int index, char str[], int offset,
                              int len)
  {
      super.insert(index, str, offset, len);
  return this;
  }

StringBuffer的insert方法:

public synchronized StringBuffer insert(int index, char str[], int offset,
                                            int len)
    {
        super.insert(index, str, offset, len);
        return this;
    }

想要系统学习JAVA推荐JAVA300集
Java300集零基础适合初学者视频教程←点击
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/332647.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号