当前位置: 首页 > news >正文

dede网站主页打不开广州seo招聘

dede网站主页打不开,广州seo招聘,史志部门建设网站 说明,在建项目人员查询网站String、StringBuffer、StringBuilder 的区别 从可变性分析 String不可变。StringBuffer、StringBuilder都继承自AbstractStringBuilder ,两者的底层的数组value并没有使用private和final修饰,所以是可变的。 AbstractStringBuilder 源码如下所示 ab…

String、StringBuffer、StringBuilder 的区别

从可变性分析

  1. String不可变。
  2. StringBufferStringBuilder都继承自AbstractStringBuilder ,两者的底层的数组value并没有使用privatefinal修饰,所以是可变的。

AbstractStringBuilder 源码如下所示

abstract class AbstractStringBuilder implements Appendable, CharSequence {char[] value;public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();//确定数组空间是否充足,若不充足则动态扩容ensureCapacityInternal(count + len);//这里会进行数组拷贝将新字符串存到数组中str.getChars(0, len, value, count);count += len;return this;}}

从线程安全性考虑

  1. String类是常量线程安全。
  2. StringBuilder 线程不安全。
  3. StringBuffer线程安全。

从性能上分析

  1. String是常量每次添加字符串都会将引用指向新的字符串。
  2. StringBuilder 非线程安全所以性能上相较于StringBuffer会快10%-15%

三者使用场景建议

  1. 操作少量数据,String即可
  2. 单线程操作大量字符串,建议使用StringBuilder
  3. 多线程用StringBuffer

为什么String 是不可变的?

从源码可以看到String底层是使用字符数组存储值的,之所以不可变是因为:

  1. value私有且final也没有对外提供字符串操作的方法。
  2. 类设置为final,子类也无法继承该类对其进行修改。
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];
}

字符串拼接用“+” 的底层工作机制是什么?

如下所示代码

public class StringTest {@Testpublic void addTest() {String s1 = "hello";String s2 = "world";String s3 = "guy";String s4 = s1 + s2 + s3;}
}

查看其字节码可以看到JVM为了避免大量常量创建,会将其进行优化,改用StringBuilder进行拼接后toString

INVOKESPECIAL java/lang/StringBuilder.<init> ()VALOAD 1INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;ALOAD 2INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;ALOAD 3INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;ASTORE 4

但是在循环体内使用+=的情况下很可能造成性能灾难。

@Testpublic void addTest2() {String[] arr = {"hello", "world", "guys"};String string = "";for (int i = 0; i < arr.length; i++) {string += arr[i];}}

可以看到在循环体内会不断创建StringBuilder进行拼接。

在这里插入图片描述

来看看我们手动创建StringBuilder 进行拼接和+=JVM优化后的性能差距

@Testpublic void addTest2() {String[] arr = new String[1000];for (int i = 0; i < arr.length; i++) {arr[i] = String.valueOf(i);}long start = System.currentTimeMillis();String string = "";for (int i = 0; i < arr.length; i++) {string += arr[i];}long end = System.currentTimeMillis();System.out.println("使用+=耗时:" + (end - start));start = System.currentTimeMillis();StringBuilder builder =new StringBuilder();for (int i = 0; i < arr.length; i++) {builder.append(arr[i]);}end = System.currentTimeMillis();System.out.println("使用StringBuilder耗时:" + (end - start));}

输出结果,可以看到StringBuilder+=快了将近6倍。

使用+=耗时:6
使用StringBuilder耗时:1

String和Object的equals() 有什么区别

Stringequals进行了重写,String比较的是字符串的值是否一致

public boolean equals(Object anObject) {if (this == anObject) {return true;}if (anObject instanceof String) {String anotherString = (String)anObject;int n = value.length;if (n == anotherString.value.length) {char v1[] = value;char v2[] = anotherString.value;int i = 0;while (n-- != 0) {if (v1[i] != v2[i])return false;i++;}return true;}}return false;}

Object比较的则是两者的引用地址是否一致

public boolean equals(Object obj) {return (this == obj);}

字符串常量池是什么,它有什么用?

如下代码所示,Java会将字符串存放在方法区的字符串常量池,后续如有变量需要可以直接复用,关于字符串常量池后文会介绍。

@Testpublic void stringConst(){String s1="s";String s2="s";System.out.println(s1==s2);//true}

图解String s1 = new String(“abc”);

这段代码实际上会创建两个对象:

  1. 创建String对象s1指向堆区的String对象
  2. 在字符串常量池中创建字符串abc

在这里插入图片描述

intern 方法是什么?有什么用?

该方法会将字符串值存放到字符串常量池中,并返回该引用。注意如果常量池存在则直接返回引用。若不存在才会创建并返回引用。

常量intern

可以看到下面这段代码,调用intern 的字符串和常量池的对象==比较返回的是true

 @Testpublic void internTest() {String s1 = "s";String s2 = s1.intern();String s3 = new String("s");String s4 = s3.intern();System.out.println(s1 == s2);//trueSystem.out.println(s3 == s4);//falseSystem.out.println(s1 == s4);//true}

常量+=intern

再补充一个神奇的现象,常量字符串进行+=时会被JVM在编译自动优化,例如String s1="a"+"b"实际上会被优化为String s1="ab",所以下面这段intern就会出现下面的结果:

原因也很简单:

对于编译期可以确定值的字符串,也就是常量字符串 ,JVM 会将其存入字符串常量池。并且,字符串常量拼接得到的字符串常量在编译阶段就已经被存放字符串常量池,这个得益于编译器的优化。 在编译过程中,Javac 编译器会进行一个叫做 常量折叠(Constant Folding) 的代码优化。
这里说到一个叫常量折叠的概念,常量折叠就是将常量表达式计算求值,并用求得的值来替换表达式,然后放到常量表中的一种机制。

@Testpublic void internTest2() {String s1 = "s"+"tring";String s2 = "string";String s3 = new String("string");String s4 = s3.intern();System.out.println(s1 == s2);//trueSystem.out.println(s3 == s4);//falseSystem.out.println(s1 == s4);//true}

这一点我们查看字节码文件就得以印证

在这里插入图片描述

final+=的intern

final字符串会被JVM优化为常量,所以下面这段代码也会返回true

@Testpublic void internTest3() {final String s1 = "hello";final String s2 = "world";String s3 = s1 + s2;String s4 = "helloworld";System.out.println(s3 == s4);//true}

查看字节码得以印证。

在这里插入图片描述

引用或者函数获取的+=

注意JVM不会对引用和方法这种动态变化的情况进行优化,所以下面这段代码就会返回false

@Testpublic void internTest3() {final String s1 = "hello";final String s2 = getStr();String s3 = s1 + s2;String s4 = "helloworld";System.out.println(s3 == s4);//false}private String getStr() {return "world";}

参考文献

Java基础常见面试题总结(中)

http://www.hkea.cn/news/855060/

相关文章:

  • 做亚马逊网站费用吗曲靖新闻今日头条
  • bing 网站管理员2023今日新闻头条
  • 深圳市做网站前十强百度一下搜索网页
  • 做执法设备有哪些网站国家免费培训学校
  • 顺德乐从有做阿里巴巴的网站吗杭州网站设计
  • 做英文网站 用阿里服务器行吗b2b网站推广排名
  • 搭建网站做淘宝客网赌怎么推广拉客户
  • 网站建设前台与后台最新技术2021最新免费的推广引流软件
  • 做网站基本语言淘宝如何提升关键词排名
  • wordpress怎样分类目录添加标签seo文章范文
  • 订阅号可以做网站吗南宁seo外包服务商
  • 邢台哪儿做网站便宜宁波 seo排名公司
  • 深圳网站优化咨询网上广告怎么推广
  • 网站右击无效是怎么做的网络营销产品
  • 中宣部网站政治建设网站服务器是什么意思
  • 淮安网站定制徐州seo外包公司
  • 嘉兴类网站系统总部网站建设技术解决方案
  • 做网站的教科书外包网络推广公司推广网站
  • 模板名字 wordpress优化大师如何删掉多余的学生
  • 3d网站建设制作百度关键词优化手段
  • 新手做那些网站比较好东莞企业网站排名
  • 欧美风格网站360指数
  • 优秀网站建设公司电话下列哪些店铺适合交换友情链接
  • 58同城乌鲁木齐网站建设重庆网站到首页排名
  • wordpress知言主题山东服务好的seo公司
  • 旅游商务平台网站建设功能需求关键词排名查询官网
  • 做网站要搭建本地服务器么微商引流被加方法精准客源
  • 网站名字要备案吗友情链接怎么弄
  • 江苏网站开发外链网站大全
  • 网站代备案流程图百度关键词优化排名技巧