1、通过构造方法创建的字符串对象和直接赋值方式创建的字符串对象区别?

通过构造方法创建字符串对象是在堆内存。
直接赋值方式创建对象是在方法区的常量池。 ==:
基本数据类型,比较的是基本数据类型的值是否相同。
引用数据类型,比较的是引用数据类型的地址值是否相同。 public class StringDemo {
public static void main(String[] args) {
String s1 = new String("hello");
String s2 = "hello";
System.out.println("s1==s2:" + (s1 == s2));//false String s3 = "hello";
System.out.println("s1==s3:" + (s1 == s3)); //false
System.out.println("s2==s3:" + (s2 == s3)); //true
}
}

画图解释:

main 方法进栈开辟空间,栈内存中执行 String s1 , new String() 出来的东西肯定是在堆内存,即有一个地址值 001 指向堆内存,

但是 “hello” 字符串不是存在于堆内存中,是存在于方法区的常量池中(原因如图),在方法区中为 “hello” 开辟空间(也有地址值),地址

值 002 赋值给了堆内存中的对象,也就是说 001 地址值中包含了一个 002 地址值,所以当输出 s1 时,栈内存中 001 指向堆内存的

001,001 又包含了 002,然后堆内存中地址值 002 指向了方法区的产量池的地址值 002 ;

当 String s2 时候,没有 new 动作,所以 s2 直接是在方法区的常量池把地址值 002 拿过来,所以 s2 直接指向方法区。

但是此时两个对象,s1 存储的是地址值 001,s2 存储的是地址值 002,所以打印 false。

当 String s3时候,没有 new 动作,所以 s3 直接是在方法区的常量池把地址值 002 拿过来,所以s3直接指向方法区。

所以此时 s2和s3的地址值是一样的 002,所以打印出 true。

总之一句话,new 的动作在堆内存,直接赋值的是在方法区的常量池。

2、Java中对字符串的优化处理

我们会经常使用 String 对象,String 对象是 java 中重要的数据类型。其设计者也对String做了大量的优化工作,

这些也是String对象的特点:不变性,常量池优化和String类的final定义。

A、不变性
String对象的状态在其被创建之后就不在发生变化。其设计者使用了 java 模式中不变模式。
作用:在一个对象被多线程共享,而且被频繁的访问时,可以省略同步和锁的时间,从而提高性能。 B、 常量池优化
如同我上面的解释,即当两个 String 对象拥有同一个值的时候,它们都只是引用了常量池中的同一个地址。 C、final 定义
String类以final进行了修饰,主要是为了“效率” 和 “安全性” 的缘故。若 String允许被继承, 由于它的高度
被使用率, 可能会降低程序的性能,所以String被定义成final。

3、String常量的累加操作优化方法。

public class StringDemo2 {
public static void main(String[] args) {
String s = ""; long beginTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
s += "s";
}
long endTime = System.currentTimeMillis();
System.out.println("s拼接100000遍s耗时:"+(endTime-beginTime)+"ms"); StringBuffer s1=new StringBuffer();
long s1BeginTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
s1.append("s");
}
long s1EndTime = System.currentTimeMillis();
System.out.println("s1拼接100000遍s耗时:"+(s1EndTime-s1BeginTime)+"ms"); StringBuilder s2=new StringBuilder();
long s2BeginTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
s2.append("s");
}
long s2EndTime = System.currentTimeMillis();
System.out.println("s2拼接100000遍s耗时:"+(s2EndTime-s2BeginTime)+"ms");
}
} 消耗时间:
s拼接100000遍s耗时:3586ms
s1拼接100000遍s耗时:3ms
s2拼接100000遍s耗时:0ms 如代码所示,使用 + 拼接字符串时候,效率很低,而使用 Stringbuffer 和 StringBuilder 的 appedn() 方法时,效率
高出 + 成百上千倍,StringBuffer 的效率比 StringBuilder 低,这是由于StringBuffer实现了线程安全,效率较低不
可避免的。所以在字符串的累加操作中,建议结合线程问题选择,应避免使用+号拼接字符串。 public class StringDemo3 {
public static void main(String[] args) { Integer num = 0;
int loop = 100000;
long beginTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
String s = num + "";
}
long endTime = System.currentTimeMillis();
System.out.println("+\"\"的方式耗时:"+(endTime-beginTime)+"ms"); beginTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
String s = String.valueOf(num);
}
endTime = System.currentTimeMillis();
System.out.println("String.valueOf()方式耗时:"+(endTime-beginTime)+"ms"); beginTime = System.currentTimeMillis();
for (int i = 0; i < loop; i++) {
String s = num.toString();
}
endTime = System.currentTimeMillis();
System.out.println("toString 方式耗时:"+(endTime-beginTime)+"ms");
}
} 消耗时间:
+""的方式耗时:20ms
String.valueOf()方式耗时:6ms
toString 方式耗时:4ms 如代码所示,String.valueOf() 直接调用了底层的 Integer.toString() 方法,不过其中会先判空;+”“ 由 StringBuilder
实现,先调用了 append() 方法,然后调用了 toString() 方法获取字符串;num.toString() 直接调用了 Integer.toString()
方法,所以效率是: num.toString() 方法最快,其次是 String.valueOf(num),最后是 num+”“ 的方式。

对 String 字符串的理解的更多相关文章

  1. 【转】String字符串相加的问题

    String字符串相加的问题 前几天同事跟我说我之前写的代码中在操作字符串时候,使用字符串相加的方式而不是使用StringBuffer或者StringBuilder导致内存开销很大.这个问题一直在困扰 ...

  2. JavaSE 学习笔记之String字符串(十四)

    API:(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源 ...

  3. 数据类型总结——String(字符串类型)

    相关文章 简书原文:https://www.jianshu.com/p/546a755c3eb6 数据类型总结——概述:https://www.cnblogs.com/shcrk/p/9266015. ...

  4. [lua]紫猫lua教程-命令宝典-L1-01-09. string字符串函数库

    L1[string]01. ASCII码互转 小知识:字符串处理的几个共同的几点 1.字符串处理函数 字符串索引可以为负数 表示从字符串末尾开始算起 所有字符串处理函数的 字符串索引参数都使用 2.所 ...

  5. String字符串性能优化的探究

    一.背景 String 对象是我们使用最频繁的一个对象类型,但它的性能问题却是最容易被忽略的.String 对象作为 Java 语言中重要的数据类型,是内存中占用空间最大的一个对象,高效地使用字符串, ...

  6. java常用类,包装类,String类的理解和创建对象以及StringBuilder和StringBuffer之间的区别联系

    一.包装类的分类: 1.黄色部分的父类为Number 继承关系: Boolean Character 其他六个基本数据类型 2.装箱和拆箱 理解:一个例子,其他的都相同 装箱:Integer inte ...

  7. Java String字符串/==和equals区别,str。toCharAt(),getBytes,indexOf过滤存在字符,trim()/String与StringBuffer多线程安全/StringBuilder单线程—— 14.0

    课程概要 String 字符串 String字符串常用方法 StringBuffer StringBuilder String字符串: 1.实例化String对象 直接赋值  String str=& ...

  8. [CareerCup] 1.3 Permutation String 字符串的排列

    1.3 Given two strings, write a method to decide if one is a permutation of the other. 这道题给定我们两个字符串,让 ...

  9. 03-Java String字符串详解

    1.Java字符串String A.实例化String字符串:直接赋值(更合理一些,使用较多).使用关键字new. B.String内容的比较 // TODO Auto-generated metho ...

随机推荐

  1. 基于Zookeeper的分布式锁

    实现分布式锁目前有三种流行方案,分别为基于数据库.Redis.Zookeeper的方案,其中前两种方案网络上有很多资料可以参考,本文不做展开.我们来看下使用Zookeeper如何实现分布式锁. 什么是 ...

  2. NIO 学习笔记三:DatagramChannel

    Java NIO中的DatagramChannel是一个能收发UDP包的通道.因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入.它发送和接收的是数据包. 打开 DatagramChann ...

  3. 支持开源,推动Orchard

    希望正在研究果园,和对果园感兴趣的,加入Orchard高级开发群,进行交流和讨论及深入研究Orchard开发,我们致力寻求志同道合推动Orchard发展的屌丝!!! 干净.专注.社区力量的圈子

  4. kubectl 常用命令总结

    # 查看所有 pod 列表, -n 后跟 namespace, 查看指定的命名空间 kubectl get pod kubectl get pod -n kube # 查看 RC 和 service ...

  5. 纯小白入手 vue3.0 CLI - 3.2 - 路由的初级使用

    vue3.0 CLI 真小白一步一步入手全教程系列:https://www.cnblogs.com/ndos/category/1295752.html 尽量把纷繁的知识,肢解重组成为可以堆砌的知识. ...

  6. 张钹院士:场景是当前AI产业化最大问题

    张钹院士:场景是当前AI产业化最大问题 https://mp.weixin.qq.com/s/TLdoi9cnY-Crr0FVp2ah6g 在世界机器人大会“青年创新创业专题论坛”上,清华大学人工智能 ...

  7. Salesforce 小知识 - 必需字段

    将字段定义为"必需" 当我们为对象设置字段的属性时,我们需要让某些字段在建立记录的时候必需有值,比如定义一个"地址"对象,那么必须填入"邮编" ...

  8. beego+vue.js分离开发,结合发布,简单部署

    大家知道,golang开发的东西部署简单是它很大的卖点,一般的应用,生成的可执行文件直接放服务器上运行即可,不需要任何环境.当然,大型的应用才需要比如mysql,nginx等. 但是当vue.js出现 ...

  9. React.js 新手教程

    正如你能从标题猜到的,这篇文章的目标是给那些有很少编程经验的读者的.比如,像我这样的人:因为迄今为止,我才探索了编程世界6个月.所以,这将是一篇新手村教程! 你只需要拥有对 HTML 和 CSS 的理 ...

  10. [20171225]查看并行执行计划注意的问题.txt

    [20171225]查看并行执行计划注意的问题.txt --//如果使用dbms_xplan.display_cursor查看并行执行计划注意一些问题,通过例子说明: 1.环境: SCOTT@book ...