zoukankan      html  css  js  c++  java
  • 转-java中的string

    转自CSDN博客,u010425776,http://m.blog.csdn.net/u010425776/article/details/50760337

    直接量创建对象更高效

    Java中,创建一个字符串有两种方法:

    //第一种方法

    String str1 = "字符串1";

    //第二种方法

    String str2 = new String("字符串2");

    这两种方式创建的字符串在使用上并无区别,但在内存分配方式上完全不同,而且效率大相径庭。下面详细阐述:

    第一种方式:

        这种方式创建的字符串对象在堆内存中只需要一块存储空间。系统只需在字符串缓冲池中创建该字符串,并将str1指向该字符串对象。

    第二种方式:

        首先创建String类型的对象,再在字符串缓冲池中创建字符串2”,并将String类型对象指向字符串2”,再将str2指向String类型对象。

        因此,第一种方式只在堆内存中开辟了一个存储空间,第二种方式在堆内存中开辟了两块存储空间。因此,第一种方式更高效。

        Java中,所有基本数据类型和String类型都有这两种创建对象的方式,我们把第一种方式称为使用直接量创建对象。因此,在Java中,使用直接量创建对象更高效!

     

    字符串缓冲池是什么?

        它存在于堆内存中,用于存储JVM运行以来所有出现过的字符串对象。

        当系统需要创建字符串时,首先判断该字符串是否存在于缓冲池中,若存在则无需创建直接引用,否则创建该字符串。因此,采用直接量方式创建的两个字符串对象是相同的:

    String str1 = "字符串";

    String str2 = "字符串";

    System.out.println(str1==str2);//结果为truestr1str2均引用字符串缓冲池中的同一个对象

    字符串经典面试题

    问:下面程序输出结果是什么?

    String str1 = "我是个大好人6";

    String str2 = "我是个"+"大好人"+6;

    System.out.println(str1==str2);

    输出结果为true!

    等号右侧的两个值均在编译时确定下来,因此它们均引用字符串缓冲池中的同一个对象。

     

    问:下面程序输出结果是什么?

    String str1 = "我是个大好人6";

    String str2 = "我是个大好人"+"我是个大好人".length();

    int len = 6;

    String str3 = "我是个大好人"+len;

    System.out.println(str1==str2);

    System.out.println(str1==str3);

    结果均为false

    由于str2和str3中含有变量或调用了函数,所以str2、str3等号右侧的值在运行阶段才能阶段确定下来,因此它们无法利用字符串缓冲池中的“我是个大好人6”。

     

    问:下面程序输出结果是什么?

    String str1 = "我是个大好人6";

    final int len = 6;

    String str2 = "我是个大好人"+len;

    System.out.println(str1==str2);

    结果为true!

    此时lenfinal修饰,len的值固定为6不会发生变化,因此在编译时可以确定str2等号右侧的值为我是个大好人6”,因此仍然可以沿用字符串池中的我是个大好人6”

     

    问:下列程序在字符串缓冲池中创建了几个常量?

    String str = "我是个"+"大好人"+6;

    答案为1个!

    该字符串中不包含变量和方法,因此在编译时即可确定,编译器看来就是一个完整的常量我是个大好人6”

     

    问:下列程序在字符串缓冲池中创建了几个常量?

    String str = "我是个";

    str = str + "大好人";

    答案为2个!

    在执行第一行代码时,常量池中创建我是个,执行第二行代码时,常量池中再创建我是个大好人,并切断str我是个的引用,指向我是个大好人,而常量我是个继续留在常量池中。

        由于缓冲池中的字符串一般不会被垃圾回收,因此通过这种拼接的方式创建的字符串将会在常量池产生很多碎片,而StringBufferStringBuilder就是为了这种问题而诞生的!

        如果一个字符串需要不断发生修改,则使用StringBufferStringBuilderString更加高效。

        StringBuilder是线程安全的,因为在其绝大多数方法都是同步方法,但因此其效率较低;

    综上所述,若程序涉及多线程,应选用StringBuilder;若单线程,则选择StringBuffer效率更高。

  • 相关阅读:
    代码题(22)— 二叉树镜像、相同的树 、对称二叉树
    代码题(26)— 不同路径
    代码题(25)— 最大子序和、最长上升子序列
    Linux 基本命令总结
    C++(五)— 控制保留小数位数
    C++(四)— 字符串、数字翻转3种方法
    代码题(24)— 寻找重复数、数组中重复的数据、找到所有数组中消失的数字
    代码题(23)— 数组中的最长山脉
    【vue】vue +element 搭建项目,将js函数变成vue的函数
    【vue】vue +element 搭建项目,$createElement使用
  • 原文地址:https://www.cnblogs.com/0402zhuhui/p/7527101.html
Copyright © 2011-2022 走看看