首页 > 编程语言 >Java中 = 和 += 的区别

Java中 = 和 += 的区别

时间:2023-06-23 09:11:40浏览次数:39  
标签:abc Java string 区别 s1 de 运算符 str

问题

  1. short s1 = 1; s1 = s1+1;有什么错?

  2. short s1 = 1; s1 += 1;有错吗?

讨论

1)+:在编译器将右边的表达式结果计算出来后,和左边的变量类型比较精度,如果左边的变量精度低于右边的结果的精度,编译器会显式的报错,告诉程序员去强制转型。(所以s1 = s1 + 1出错)最后将表达式的结果复制到变量所在的内存区。

2)+=:编译器自动隐式直接将+=运算符后面的操作数强制装换为前面变量的类型,然后在变量所在的内存区上直接根据右边的操作数修改左边变量内存存储的二进制数值(所以 s += 1不报错)最后达到和赋值运算符相同的目的。与前者相比,由于后者是位操作,效率也较前者高。

C++ string类的+与+=运算符

一、string对象的运算符+和运算符+=效率差很多,+比+=更耗时间更占空间。

​ 以下两句str=str+a;str+=a;看起来差不多,其实效率差很多。

string str,a;
str=str+a;
str+=a;
123


​ 今天在力扣上写代码,同一道题,同样的代码,差别就是我把str+=a;改成了str=str+a;运行时间翻了倍,而且内存消耗多了十几倍,如图:
在这里插入图片描述
​ 虽说力扣上的运行时间会有波动,但也不至于差别这么大,然后我去搜了好些博客看,有些博主实际运行验证了在string的使用中,使用+=比使用+快很多。我翻《C++ Primer》,大概知道了原因。

原因:

  • str=str+a;会先将等号右边的两个string对象内容相加,得到一个新的string对象,再把这个新的对象赋给等号左边的string对象。
  • str+=a;直接将等号右边的string对象内容追加到左边的string对象后面
  • 这两者的差别就是,+相比于+=在这个过程中会多产生一个新对象,创建新对象,不仅要时间,新的对象还要占内存,所以+=效率较高。

二、为什么我在使用string的+运算或+=运算时会报错?


①例如在string后加上几个常量字符串:

string s1="abc" +"de";    // 错误

原因

  • 之所以两个string能相加,是因为string类把运算符+和+=都重载过,+和+=是string的重载函数。也可以把string和字符串常量相加,但必须保证每个加法运算符(+)的两侧的运算对象至少有一个是string
  • 上面例子中的"abc"、"de"都是字符串常量(const char类型),char是数据的基本类型,不是类,更没有重载过+和+=运算符,是没办法用加号直接相加的,所以会报错。

②为什么s1= s1+“abc”+“de” 是对的,s1+= “abc”+“de” 就错了?

string s1;
s1=s1+"abc"+"de";  // 正确
s1+="abc"+"de";	   // 错误

原因:

  • s1=s1+"abc"+"de"是对的。前面提到,把string和字符串常量相加,但必须保证每个加法运算符(+)的两侧的运算对象至少有一个是string。s1+"abc"+"de"按照加号从左向右结合的顺序,会先让s1+“abc”,再让这个结果加上"de",然后把这个结果赋给s1。是合法的。
  • s1+="abc"+"de"错了。因为要先得到+=右边的内容,也就是进行"abc"+"de",字符串常量(const char类型)没有办法直接相加。

再举一个例子:

string s1="abcde";
string s2;
s2+=s1[0]+s1[1]+s1[2];	// 错误

原因:
s1[n]返回的是s1的第n个字符的引用,是char类型,+=要先得到等号右边的内容,即进行s1[0]+s1[1]+s1[2],但char是不能直接相加的(几个char直接相加编译器会将它们对应的ASCII码相加,得到一个int型的数,得不到你想要的字符串拼接的效果),所以错了,改成s2=s2+s1[0]+s1[1]+s1[2];是ok的。

总之:在string使用时用+或+=出错,可能是你将两个字符串常量或者char直接相加了。一定要保证每次+的时候,+是在对至少一个string进行操作(可以两个string相加,也可以一个string加上一串字符串常量)。

标签:abc,Java,string,区别,s1,de,运算符,str
From: https://www.cnblogs.com/javaxubo/p/17498729.html

相关文章

  • Java基础:自动装箱和自动拆箱
    感谢,原文链接:https://www.cnblogs.com/dolphin0520/p/3780005.htmlJava的自动包装类型首先基本数据类型:4类8种基本数据类型对应包装器类byte(1字节)Byteshort(2字节)Shortint(4字节)Integerlong(8字节)Longfloat(4字节)Floatdouble(8字节)Doublechar(2字......
  • 现实中的 JAVA (一)
    买零食描述本例子主要是通过JAVA语言来描述,平时父母带我们去买零食的场景。买零食流程图从家里出发,选择一种出行方式达到零食店然后我们就可以开始购物了,选择对应的零食随后进行买单家庭成员UML图1、Person做为顶级的抽象类2、Male作为男CLass的描述类3、Fem......
  • JAVA博客3
     一.前言第三次写Blog,相比较上一次而言自己的经验更加的丰富了,这次blog的书写相对来说要更为轻松些。内容上题目较少,只需要分析有关课程成绩统计系统,但是说容易也并不容易,每一道题都是刺头中的刺头,这一次写博客,不仅仅是以完成任务的目的,更多的,让自己重新对那些打击过自己,折磨过......
  • 系统调用与库函数的区别
    1.运行空间   库函数是在用户空间运行,而系统调用是在内核空间运行的2.是否有缓冲  库函数有缓冲区, 而系统调用没有缓冲区3.开销大小  库函数开销小,因为库函数设置了缓冲区,减少了内核空间与用户空间之间的切换带来的开销,           而系统调......
  • java中的各种锁
    java中的各种锁一、概述乐观锁CAS悲观锁synchronized自旋锁CAS可重入锁synchronized、Reentrantlock、Lock读写锁ReentrantReadWriteLock,CopyOnWriteArrayList、CopyOnWriteArraySet公平锁Reentrantlock(true)非公平锁synchronized、reentrantlock(false)共享锁......
  • Java Web自定义MVC框架详解
    最近给学生讲JavaWeb,希望他们能够在学完这部分内容后自己实现一个MVC框架。但是突然发现百度上能搜索到的靠谱的资料并不是很多,有些只是原理没有代码实现,有些有代码实现但是对于初学者来说理解起来还是比较困难,于是决定把自己讲自定义MVC框架的内容放在这里分享给大家,不仅仅是代码......
  • 字符编码和Java中的乱码问题
    ASCII码  在计算机内部,所有的信息最终都表示为一堆二进制形式的数据。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,称为一个字节(byte),从0000000到11111111。上世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系做了统一规定,称之为ASCII......
  • Java Web项目中使用Freemarker生成Word文档
    Web项目中生成Word文档的操作屡见不鲜,基于Java的解决方案也是很多的,包括使用Jacob、ApachePOI、Java2Word、iText等各种方式,其实在从Office2003开始,就可以将Office文档转换成XML文件,这样只要将需要填入的内容放上${}占位符,就可以使用像Freemarker这样的模板引擎将出现占位符的地......
  • [连载]Java程序设计(05)---任务驱动方式:简单的加密/解密系统
    任务:还是上一家公司,现在该公司在全国各地都设立了自己的分公司以拓展其核心业务,那么就需要利用互联网在全国各地的公司之间传递信息(我们假定这些信息就是文字信息),这些信息可能涉及一些商业机密,为此公司需要一套简单的加密和解密系统来避免直接在互联网上传递明文信息。目前拟定了两......
  • 历史最全Java资源大全中文版整理分享
       很多程序员应该记得GitHub上有一个Awesome-XXX系列的资源整理。本资源对Java相关的资源列表进行翻译和整理,内容包括:构建工具、数据库、框架、模板、安全、代码分析、日志、第三方库、书籍、Java站点等。分享给需要的朋友。目录内容截图......