最新要闻
- 全球热点评!国产GPU公司景嘉微募资42亿:研发高性能显卡 可用于大型游戏
- 积极拥抱生僻字!阿里普惠体推出3.0版本:免费商用-当前讯息
- 今日关注:为何坚持使用高压油箱?吉利研究院副院长:常压油箱不可能达标
- 音视频会议神器!阿里云通义听悟正式发布:轻松记录总结、实时翻译
- 2K-3K价位段无敌!Redmi K60斩获618首销双冠军|每日讯息
- 天天新消息丨淘宝开店多少钱能开直通车_淘宝开店多少钱
- 低到13.48万元起步 江西五十铃现款D-MAX年中大促_全球热点评
- 被人类幼崽萌化的瞬间:画面实在太可爱!祝愿大家六一快乐
- 访华后特斯拉股价大涨 马斯克重返世界首富宝座
- 播报:老外试驾法拉第未来FF 91被震撼:从未见过副驾驶有屏幕的车子
- 旧机福音 极限精简版Win10系统Tiny10更新:64位支持来了|全球百事通
- 坐飞机也要称体重 新西兰航空登机前将给国际旅客称重-天天热推荐
- 仙佑膏药逐步实现标准化 公司规范化生产管理水平
- 环球热文:南运河南路与金钟桥大街交口车行道调整
- 全球快报:14代酷睿有望首发 Intel开发Wi-Fi 7芯片:网速狂飙4.8千兆
- 热点!男孩六一表演化身行走表情包 全情投入阳光自信:网友看笑不愧C位
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
编写Java代码时应该避免的6个坑
通常情况下,我们都希望我们的代码是高效和兼容的,但是实际情况下代码中常常含有一些隐藏的坑,只有等出现异常时我们才会去解决它。本文是一篇比较简短的文章,列出了开发人员在编写 Java 程序时常犯的错误,避免线上问题。
1、大量使用 Enum.values
Enum.Values()
的问题在于,按照规范它的返回必须是一个不可变的列表。为了实现这一点,它在每次调用时返回一个带有枚举值的新数组实例。
public enum Fruits { APPLE, PEAR, ORANGE, BANANA; public static void main(String[] args) { System.out.println(Fruits.values()); System.out.println(Fruits.values()); }}// output[Lcom.test.Fruits;@7ad041f3[Lcom.test.Fruits;@251a69d7
它们是内存中的两个独立对象,这好像也没啥事,但是如果在处理大量请求时使用 Fruit.values()
并且机器负载很高,这可能会导致内存升高等问题。
【资料图】
public class Main { public static final Fruits[] values = Fruits.values(); public static void main(String[] args) { System.out.println(values); System.out.println(values); }}// output[Lcom.wayn.data.elastic.config.Fruits;@4534b60d[Lcom.wayn.data.elastic.config.Fruits;@4534b60d
如上我们可以通过引入私有静态最终变量 values
来缓存它们来轻松解决此问题。
2、将 Optional 作为方法参数传递
如下代码
LocalDateTime getCurrentTime(Optional zoneId) { return zoneId.stream() .map(LocalDateTime::now) .findFirst() .orElse(LocalDateTime.now(ZoneId.systemDefault()));}
我们传递可选的 zoneId 参数,并根据它的存在来决定是在系统时区中给出时间还是使用指定的时区。但是,这不是正确使用 Optional 的方式。我们应该避免将它们用作参数,而是使用方法重载。
LocalDateTime getCurrentTime(ZoneId zoneId) { return LocalDateTime.now(zoneId);}LocalDateTime getCurrentTime() { return getCurrentTime(ZoneId.systemDefault());}
如上代码明显更易于阅读和调试。
3、使用字符拼接
Java 中的字符串是不可变的。这意味着一旦创建它们就不再可编辑。 JVM 维护一个字符串池,在创建一个新字符串之前,它调用 String.intern()
方法,该方法从字符串池中返回一个与值匹配的实例(如果存在)。
假设我们想通过连接东西来创建一个长字符串
String longString = "";longString +="start";longString +="middle";longString +="middle";longString +="middle";longString +="end";
不久前,我们被告知这是一个非常糟糕的主意,因为Java的旧版本执行以下操作
- 在第 1 行中,字符串 "start" 被插入到字符串池中,longString 指向它
- 在第 2 行中,字符串 "startmiddle" 被添加到池中,longString 指向它
- 在第 3 行,我们有 "startmiddlemiddle"
- 在第 4 行 "startmiddlemiddlemiddle"
- 最后,在第 5 行,我们将 "startmiddlemiddlemiddleend" 添加到池中并将 longString 指向它
所有这些字符串都保留在池中并且从不使用,这会浪费大量 RAM。
为了避免这种情况,我们可以使用 StringBuilder
String longString = new StringBuilder() .append("start") .append("middle") .append("middle") .append("middle") .append("end") .toString();
调用 toString 方法时,StringBuilder 仅创建一个字符串,从而为我们保存了最初添加到池中的所有中间字符串。但是,在 Java 5 之后,编译器会自动为我们完成此操作,并且可以安全地使用带有 "+" 的字符串连接。
此规则有一个例外,那就是在循环中进行字符串连接时
String message = "";for (int i = 0; i < 10; i++) { message += "msg" + i;}System.out.println(message);
这段代码不会被 JIT 优化,每次迭代都会将新的字符串插入到字符串池中,这里我们必须使用 StringBuilder
StringBuilder msgB = new StringBuilder();for (int i = 0; i < 10; i++) { msgB.append("msg").append(i);}System.out.println(msgB);
这里还有几件事要注意
即时编译器有时会重新组织代码。
String s = "1" + "2" + "3";
转换成
String s = "123";
从 Java 15 开始,可以使用文本块处理多行字符串:
String sql = """ SELECT * FROM users as u WHERE u.name = "John" AND u.age > 34""";
4、过度使用原始包装器
考虑以下两个片段
int sum = 0;for (int i = 0; i < 1000 * 1000; i++) { sum += i;}System.out.println(sum);// ----------------------Integer sum = 0;for (int i = 0; i < 1000 * 1000; i++) { sum += i;}System.out.println(sum);
在我的机器上,第一个比第二个快 6 倍。唯一的区别是我们使用包装器 Integer 类。这样做的原因是,在第 3 行中,运行时必须将 sum 变量转换为原始 int(自动拆箱),并且在执行添加后,结果将包装在一个新的 Integer 类中(自动装箱)。这意味着我们创建了 100 万个 Integer 类并执行了 200 万个装箱操作,这解释了速度急剧下降的原因。
仅当需要将包装类存储在集合中时才应使用包装类。但是,未来的 Java 版本将支持原始类型的集合,这将使包装器过时。
5、自己编写哈希函数
当我们想将对象存储在 HashMap 中时,通常会实现对象的哈希函数。该 HashMap 由带有数字的 "桶" 组成,每个哈希码都分配给一个特定的桶。如果存入 "桶" 对象的哈希函数没有正确编写,HashMap 的性能将显着降低。一个写得很好的散列函数将确保所有键的平均分配。
在一般情况下我们需要自己编写哈希函数,但在大多数情况下,使用内置的 Objects.hash(...)
方法就行,该方法为一系列输入值生成哈希代码,生成散列代码的方式就像将所有输入值都放入一个数组中一样,并且通过调用 Arrays.hashCode(Object[])
对该数组进行散列。
public class Car { private final String model; private final Integer year; private final Instant manufactureDate; public Car(String model, Integer year, Instant manufactureDate) { this.model = model; this.year = year; this.manufactureDate = manufactureDate; } @Override public int hashCode() { return Objects.hash(model, year, manufactureDate); } @Override public boolean equals(Object obj) { // 在实现 hashCode 时,不要忘记实现 equals }}
6、使用 java.util.Date
我们甚至应该避免 java.util 中的所有时间类改用 java.time 包。
Date 类已被弃用,原因有很多,它有很多设计缺陷。
- 它不是无法被修改的
- 它无法处理时区
- 充满已弃用但仍在使用的遗留代码
当程序中出现对日期支持的需求时,util 包中的 Date、Calendar 和 rest time 类就出现了。鉴于如上缺陷,程序界有几次修复它们的尝试,但最后他们决定引入一个新的包 java.time。 java.time 包与第三方的 joda.time 非常相似,这意味着我们不需要在使用 joda.time,Jdk8 已经有了内置支持。
我们列出 java.time 中使用的三个最重要的类
LocalDate
表示特定时区的日期(不包括一天中的时间)。
LocalDate.of(2022, 6, 12);LocalDate.parse("2022-06-12");// The Date/Time API in Java works with the ISO 8601 format by default, which is (yyyy-MM-dd)// We can overwrite it like thisLocalDate.parse("2022.06.12", DateTimeFormatter.ofPattern("yyyy.MM.dd"));
LocalDateTime
与 LocalDate 相同,但它有一天中的时间。
LocalDateTime.of(2022, 6, 12, 10, 34, 18);var dateTime = LocalDateTime.parse("2022-06-23T10:34:18");// it"s easy to get the time in a different zonedateTime.atZone(ZoneId.of("GMT+2"));
Instant
我最喜欢的。它本质上是 LocalDateTime,但强制使用 UTC 时区。在应用程序中需要处理时区时,最好在所有服务和数据库中使用同一个时区。当使用 Instant 时,一切都变成了 UTC,然后读者可以根据需要将其转换为不同的时区。
// Current time in UTCInstant.now();// Note the "Z" at the end it means UTCInstant.parse("2022-06-21T12:12:12Z");// Convert instant to a different time zoneInstant.now().atZone(ZoneId.of("GMT+3"));
简单来说
- 不要使用日期和日历(或任何与 java.util 相关的日期)
- 不要使用 joda.time(因为它与 java.time 非常相似)
- 如果只对某个区域的日期感兴趣,请使用 LocalDate
- 如果对某个区域的日期和时间感兴趣,请使用 LocalDateTime
- 如果需要日期时间并且不想处理时区,请使用 Instant
本文翻译自国外论坛 medium,原文地址:https://medium.com/@b.stoilov/things-to-avoid-while-writing-java-cd078e5aa61c
关注公众号【waynblog】每周分享技术干货、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力!
关键词:
编写Java代码时应该避免的6个坑
Linux实验文档
Python装饰器
全球热点评!国产GPU公司景嘉微募资42亿:研发高性能显卡 可用于大型游戏
积极拥抱生僻字!阿里普惠体推出3.0版本:免费商用-当前讯息
今日关注:为何坚持使用高压油箱?吉利研究院副院长:常压油箱不可能达标
音视频会议神器!阿里云通义听悟正式发布:轻松记录总结、实时翻译
2K-3K价位段无敌!Redmi K60斩获618首销双冠军|每日讯息
天天新消息丨淘宝开店多少钱能开直通车_淘宝开店多少钱
全球滚动:攻防世界_PWN_stack2
世界热头条丨MySQL表列数和行大小限制
天天观热点:为什么JS中0.1+0.2不等于0.3
美国会众议院通过债务上限法案 全球热点评
低到13.48万元起步 江西五十铃现款D-MAX年中大促_全球热点评
被人类幼崽萌化的瞬间:画面实在太可爱!祝愿大家六一快乐
访华后特斯拉股价大涨 马斯克重返世界首富宝座
播报:老外试驾法拉第未来FF 91被震撼:从未见过副驾驶有屏幕的车子
旧机福音 极限精简版Win10系统Tiny10更新:64位支持来了|全球百事通
坐飞机也要称体重 新西兰航空登机前将给国际旅客称重-天天热推荐
仙佑膏药逐步实现标准化 公司规范化生产管理水平
在 Ubuntu 上使用 ADB 备份 Android 数据 世界热议
环球热文:南运河南路与金钟桥大街交口车行道调整
全球快报:14代酷睿有望首发 Intel开发Wi-Fi 7芯片:网速狂飙4.8千兆
热点!男孩六一表演化身行走表情包 全情投入阳光自信:网友看笑不愧C位
26次高考落榜大叔继续冲击重本 网友吐槽哗众取宠、炒作:本人回应
【速看料】马斯克到访特斯拉上海超级工厂 陶琳深夜发声:激动人心 收获满满
头条:关于nokia_6270的问题
大数据面试题集锦-Hadoop面试题(二)-HDFS
世界关注:人民币汇率跌破7.1,原因是什么?专家解读
被苹果抛弃了!初代iPad Air被列为过时产品 观天下
超越苹果M2 AMD锐龙7000全新AI性能实战:等14代酷睿来战-世界关注
售价超2万元!苹果首款头显Reality Pro高清渲染图出炉:下周发布
环球关注:马娘翻译:被白兴大人附身的福来
2023年4月和5月随笔
儿童节的梦想!妈妈 我想要一本“黑客攻防指南”
热议:CPU时代又回来了?英伟达股价大跌5% 英特尔逆势上涨
SD协议-状态机-天天观速讯
世界微动态丨哪种商业医疗保险好呢_比较好的商业医疗保险
环球关注:杀6000万头差点灭绝 奉为国兽还杀:为何美国跟野牛过不去?
四辆车狭路相逢挤一起 网友:两车道整出四车道|天天通讯
世界热议:一个时代落幕!《英联联盟》今日13.11版重磅更新:正式放弃32位系统
美女云集!网飞韩剧《绝世网红》中字预告首曝:宋雨琦客串 世界观速讯
儿童节快乐!今天6月1日 微信上线卖萌、带娃限时状态
天天新资讯:禾的组词一年级云组词_禾的组词一年级
大戏看北京 6月文艺资讯-每日资讯
发现增加了预防链球菌感染的希望 环球快讯
车贷担保人会影响征信吗
今日热闻!小迪网安笔记一:基础入门
世界微头条丨Doris(六) -- 查询语法和内置函数
重装系统之后发现网卡驱动丢了,怎么办?一招解决_世界简讯
云从科技:目前基础部分的算力需求能够被基本满足_全球热资讯
暴雪对《暗黑破坏神4》服务器感觉良好:我们准备好了!
【独家焦点】电影《诛仙1》CCTV6今晚开播收视登顶!肖战、李沁主演
天天滚动:注意!江苏苏州将发放1亿元购车补贴 一次性可补五千
日版实体版《死亡细胞:重返恶魔城》将9月14日发售 为特别好评作品
真人电影《勿言推理》追加演员阵容公布 永山瑛太将出演影片
《原神》七圣召唤国际大赛将于今年举办 为上线以来首次官方国际赛事
玩家打造全球最小GC主机 方正小巧造型吸引众人的喜爱
BOSS直聘-W:耗资约400万美元回购近58.76万股-环球快看点
动画声优大西沙织因健康状况恶化将减少工作活动 曾配音《路人女主》
广东汕尾台风天刮来众多生蚝 两人一小时收获两百多斤
《斗罗大陆2》被曝最新路透照 张予曦饰演的小舞白裙绝美可人
2023新一线城市名单公布 北方仅有四座城市上榜
“高考钉子户”梁实马上迎来其第27次高考 称准备相对充分
15)触发器
天天微动态丨小程序容器助力航空企业数字化转型
全球新动态:2.单向链表
Quartz任务调度框架 世界报资讯
视点!掌握嵌入式Linux编程0简介
月度回望|“资产荒”逻辑未破 5月债市现券收益率曲线陡峭下移
当前头条:日本最大啤酒商要重返中国:你爱日啤、德啤还是国啤?
3999元起 华为Vision智慧屏3开售:720P秒变4K
刀塔循环圈单机地图 刀塔循环圈-天天即时看
React Native+小程序容器=更高的开发效率_焦点热门
全球热议:uniapp uni-number-box组件 步长为1,还能输入小数思路分享
Linux工作原理3设备 天天简讯
2023-05-31:给定一个整数数组 A,你可以从某一起始索引出发,跳跃一定次数 在你跳跃的过程中,第 1、3、5... 次跳跃称为奇数跳跃 而第 2、4、6
世界微动态丨货币市场日报:5月31日
“暖蜂驿站”温暖“两新”群体 相城区太平街道打造“15分钟暖蜂服务圈”-每日关注
首发2999元 联想百应新款迷你主机上架:13代i5、机身仅0.5L 全球快消息
满油满电续航1370公里 加速7秒内!吉利银河L7上市:13.87万起|世界观焦点
NVIDIA发布535.98驱动更新:大幅提升《暗黑破坏神4》帧数 每日快讯
当前观察:4799元开售!一图看懂努比亚Z50 Ultra摄影师版:玻璃“皮革”独一家
c#使用内存映射像处理内存一样去快速处理文件_全球热头条
重学c#系列——DiagnosticListener [三十五]|每日热门
市场监管总局:CCC认证制度实施以来,儿童玩具合格率显著提升 每日关注
从蔚小理到理小蔚 蔚来汽车做高端砸换电能否逆袭?|今日报
华为凌霄子母路由Q6E正式开售:电线变网线 全屋Wi-Fi满格
《小美人鱼》内地票房突破2000万!累计观影人次达54.7万 全球报道
摩尔线程显卡支持DX11游戏!国产第一家
针刺只是小儿科!吉利银河L7电池遭“蹂躏”:跌落水泡火烧撞击均无碍
天天热头条丨记录--Js基础练习题目
Apache DolphinScheduler 3.0.6 发布,或将是最后一个 3.0.X 版本|当前播报
债市日报:5月31日
航天宏图: 公司无人机业务:业务领域覆盖国土测绘、环保监测、河道监测、电力巡检、管道巡线、灾情监测等
或有剧毒!印度学生午餐中现20厘米死蛇:多人进餐后呕吐昏迷 环球要闻
风头盖过马斯克访华 贾跃亭新车220万开卖!FF 91最全解析 世界速递
全球今日讯!新型太阳能电池问世:柔韧性极高 弯曲角度可超360度
中兴晴天墙面路由器上手:新一代WiFi 6穿墙神器
明星餐饮为何逃不出短命魔咒?专家解释原因 全球速读