Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >记一次愚蠢的操作--String不可变性

记一次愚蠢的操作--String不可变性

作者头像
Java3y
发布于 2019-07-20 08:28:27
发布于 2019-07-20 08:28:27
48500
代码可运行
举报
文章被收录于专栏:Java3yJava3y
运行总次数:0
代码可运行

前言

只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

记录一次在写代码时愚蠢的操作,本文涉及到的知识点:String不可变性

一、交代背景

我这边有一个系统,提供一个RPC接口去发送短信。外部调用我的接口需要传入手机号等等参数,我这边负责解析这些参数、做一些业务的处理,然后调用短信渠道商的接口发送短信。

每当调用完短信渠道商的接口时,我会对这次发送的记录入库(存入MySQL中),同样地短信渠道商会返回发送或失败的回执给我,我也会入库(存入MySQL中)。

那天,有人来找到我,说某个手机号收不到短信,用户并没有屏蔽短信(欠费、关机)等等一些操作,就是收不到短信。

于是我就去排查啦,首先我先去DB里边找有没有对应的发送记录,发现这条记录是存在的,而且在DB上看不出来有什么异常。

  • 所以,这就排除了这个操作在中途被拦截的情况(因为已经入库了,就肯定调用过短信运营商的接口)

后来就去捞日志,看看调用短信运营商返回的Result对象的信息是什么,然后就去问了一下短信运营商可能出现这种问题的原因是什么。那边回复的是:“如果是部分的手机号出现这种状况,是不是你们的手机号没有trim啊?

于是,我又去捞日志,发现手机号后面真的带有一个空格(扎心了,之前一直看不到)。要处理这个问题就变得异常简单了,我只要在入口里边对手机号进行trim就好了。

二、编写代码

我这边是支持同一条短信向多个手机号发送,于是手机号我这边用的是HashSet来进行接收。对手机号进行trim我写下了如下的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 说明:Task对象 有个 key属性,这个key属性的类型是HashSet

if (task.getKey() != null && task.getKey().size() > 0) {
    for (String s : task.getKey()) {
        s.trim();
    }
}

代码很简单,我做的就两步:

  • 判断是否为null,不为null值则遍历手机号集合
  • 对每个手机号进行trim

上面的代码有问题吗?必须有问题啊,没问题我还写啥。

下面写个小Demo,我们会发现:在代码的11行上调用trim()方法后,在12行再输出,还是会有空格的情况。

代码示例

2.1 为什么会有这种错觉?

其实,我们在初学Java的时候,肯定会学到String类。在学习的时候也是明确String是不可变的,但总是有个感觉我们把String对象给改了,为什么?

不可变的String

我觉得第一点是这样的:我们操作的往往是可变的对象,对象的某些属性改了,我们就认为已经改了。比如下面的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
HashSet<Student> students = getStudent();
for (Student s1 : students) {
    s1.setName("Java3y");
}

执行完,我们就认为在HashSet里边的Student的名字全改成Java3y了,而实际上也是如此。

我觉得第二点是这样的:我们平时操作String对象,都是直接把操作后的结果传过去,这看起来就像修改原对象了一样。比如下面类似的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 去重
String phone = "   137888888888    ";
sendPhone(phone.trim());

// 转成大写后输出
System.out.println(phone.toUpperCase());

// ... 等等

返回一个新的String对象

2.2 怎么改

现在问题已经知道了,String对象是不可变的,对String对象进行操作,“看似”把原来的String对象改了,实际上是生成了一个新的String对象。

回到我那个问题,也很好解决,把trim好的手机号设置到HashSet就行了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 说明:Task对象 有个 key属性,这个key属性的类型是HashSet

HashSet<String> hs = new HashSet();
if (task.getKey() != null && task.getKey().size() > 0) {
    for (String s : task.getKey()) {
        hs.add(s.trim());
    }
}
task.setKey(hs);
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java3y 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
记一次愚蠢的操作--线程安全问题
我这边有一个系统,提供一个RPC接口去发送各种信息(比如短信、邮件、微信)等等渠道。我这边的系统架构是这样的:
Java3y
2019/08/05
4210
记一次愚蠢的操作--线程安全问题
用户微服务用户注册功能实现
用户注册之前需要先给注册的手机号发送一条验证码,我们把验证码存储在Redis中。 发送的时候我们先把验证码存储到Redis,然后用户发起注册的时候取出验证。
共饮一杯无
2022/11/28
1.4K0
用户微服务用户注册功能实现
python中的twilio入门
Twilio是一个提供通信API服务的平台,可以让开发者通过代码实现短信、电话和视频等功能。在Python中,Twilio提供了一个方便易用的库,使得使用Twilio API变得简单,本文将介绍如何在Python中入门使用Twilio。
大盘鸡拌面
2023/10/24
1.4K1
聊聊如何在Java应用中发送短信
很多业务场景里,我们都需要发送短信,比如登陆验证码、告警、营销通知、节日祝福等等。
勇哥java实战
2023/11/07
8010
瑞吉外卖-移动端开发
目前市面上有很多第三方提供的短信服务,这些第三方短信服务会和各个运营商(移动、联通、电信)对接,我们只需要注册成为会员并且按照提供的开发文档进行调用就可以发送短信。需要说明的是,这些短信服务一般都是收费服务。
用户9615083
2022/12/25
8720
瑞吉外卖-移动端开发
腾讯云短信服务实现 Java 发送手机验证码(SpringBoot+Redis 实现)
前置:需要腾讯云的账号,后期授权需要,不需要买云服务器,有需要的可以购买短信套餐(几块钱)
RAIN7
2022/08/23
3.5K0
腾讯云短信服务实现 Java 发送手机验证码(SpringBoot+Redis 实现)
一次短信验证码整改实验
这个短信验证码在并发量非常大的情况下有可能会失效,后续会进行整改升级,保证线程安全
阿东
2021/08/16
1.1K0
Spring 四种方式教你异步接口返回结果
使用场景:用户绑定邮箱、手机号,将邮箱、手机号保存入库后发送邮件或短信通知 接口要求:数据入库后给前台返回成功通知,后台异步执行发邮件、短信通知操作
鱼找水需要时间
2023/02/16
1.7K0
Spring 四种方式教你异步接口返回结果
180行代码实现全球短信发送功能(无SKD依赖)
本文提供的代码不依赖官方SDK,为方便读者理解,文章中提供的代码片段包含详细的注释。完整功能代码见文末,删减冗余注释和空行后不足180行。
若海
2023/08/12
18K1
C# 实现发送手机短信
现在很多网站都是短信发送的功能,怎么实现的呢。对于个人站长来说的话,通过使用SMS短信通API接口相对比较划算和简单。那怎么实现呢,步骤如下: 1. 从网上(http://sms.webchinese
逸鹏
2018/04/09
4.9K0
C# 实现发送手机短信
Android开发笔记(五十五)手机设备基本操作
手机的基本信息分两类,一类是与电话有关的信息,另一类是设备自身的信息。 与电话有关的信息可由TelephonyManager类获得,常用的参数与对应的方法如下所示: 网络运营商名称 : getNetworkOperatorName 网络运营商编号 : getNetworkOperator,返回五位数字,前三位表示国家代码(中国的为460),后两位表示运营商代码(中国移动为0,中国联通为1,中国电信为2) 手机类型 : getPhoneType 网络类型 : getNetworkType获得细分类型,getNetworkClass获得大类如2G/3G/4G SIM卡状态 : getSimState SIM卡运营商名称 : getSimOperatorName SIM卡运营商编号 : getSimOperator SIM卡序列号 : getSimSerialNumber IMSI : getSubscriberId IMEI : getDeviceId 手机号码 : 实测发现多数情况下getLine1Number和getMsisdn都无法正确取到号码,但是很多APP又需要用户的手机号,那又得想办法获取号码,获取的方法大致有如下几种: 1、用户首次使用,提示用户注册手机号,然后保存起来,下次就能取到手机号了; 2、APP自动用该手机发一条免费短信(比如向10086发),然后到发件箱中寻找该短信的发送号码; 3、如果能连到运营商的支撑系统,那么根据IMSI去后台系统查询手机号,这也是可以的; 设备自身的信息可由Build类获得,常用的参数与对应的方法如下所示: 手机厂商 : Build.MANUFACTURER 手机品牌 : Build.BRAND 手机型号 : Build.MODEL 设备名称 : Build.DEVICE CPU指令 : Build.CPU_ABI 芯片型号 : Build.HARDWARE 手机序列号 : Build.SERIAL SDK版本 : Build.VERSION.SDK_INT 系统版本 : Build.VERSION.RELEASE 版本代号 : Build.VERSION.CODENAME
aqi00
2019/01/18
1.2K0
三个月写了个短信平台,开源出来!
大家好,我是勇哥。花了三个月的时间,我手写了个短信平台服务 platform-sms,今天开源出来 Beta 版本。
勇哥java实战
2023/11/26
1.5K1
简单几步,用云开发搞定短信验证码登录
短信验证码登录支持在客户端使用短信验证码进行登录,封装了短信验证码的生成、发送、校验和定时清理逻辑,帮助开发者进行鉴权。登录成功后,用户身份将转化为正式用户。
腾讯云开发TCB
2020/09/08
2.1K0
【笔记整理】SpringBoot集成腾讯云短信
前言 记录一下最近使用SpringBoot基础腾讯云里的短信产品功能的体验。 1、腾讯云申请开通短信服务。 2、配置短信内容:分别创建签名、模板和群发短信。 3、使用SpringBoot工程集成测试。
pbinlog
2022/04/18
8.2K0
记两次简单的edusrc挖掘
服务器程序并未对请求次数进行限制,或者是限制不严格导致,导致可以大量重复发送短信验证码。该漏洞会对其他用户造成骚扰或使厂商的运营商短信费用的增加,造成损失。
没事就要多学习
2024/07/18
1230
记两次简单的edusrc挖掘
商城项目-发送短信功能
请参考资料 https://cwl-java.blog.csdn.net/article/details/103819145
cwl_java
2020/01/14
2.2K0
商城项目-发送短信功能
手把手带你在集成SpringSecurity的SpringBoot应用中添加短信验证码登录认证功能
在上一篇文章一文理清SpringSecurity中基于用于名密码的登录认证流程中笔者有详细地介绍了Spring Security登录认证的流程,也为我们在工作中面需要实现自定义的登录认证如手机号+短信验证码、邮箱地址+邮箱验证码以及第三方登录认证等方式的扩展做好了准备。那么本文,笔者就手把手带大家实现在集成了Spring Security的SpringBoot项目中如何增加一种手机号+短信验证码的方式实现登录认证。
用户3587585
2022/04/14
2.5K0
手把手带你在集成SpringSecurity的SpringBoot应用中添加短信验证码登录认证功能
Fdog系列(三):使用腾讯云短信接口发送短信,数据库写入,部署到服务器,web收尾篇。
Fdog系列(一):思来想去,不如写一个聊天软件,那就从仿QQ注册页面开始吧。 Fdog系列(二):html写完注册页面之后怎么办,用java写后台响应呀。
花狗Fdog
2021/05/06
2.5K0
批量任务体现多线程的威力!
对于多线程的理解不是非常深刻,工作中用到多线程代码的机会也不多,前不久遇到了一个使用场景,通过编码实现后对于多线程的理解和应用有了更加深刻的理解。场景如下:现有给用户发送产品调研的需求,运营的同事拿来了一个Excel文件,要求给Excel里面大约六万个手机号发送调研短信。
翎野君
2023/05/12
2870
JAVA实现利用第三方平台发送短信验证码
前段时间自己做的一个小项目中,涉及到用短信验证码登录、注册的问题,之前没涉及过这一块,看了别人的博客其实也是似懂非懂的,现在就将自己做的利用第三方短信平台来发送验证码这个功能记下来。
用户7353950
2022/06/23
6.2K0
JAVA实现利用第三方平台发送短信验证码
推荐阅读
相关推荐
记一次愚蠢的操作--线程安全问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验