Java 中常见的几个陷阱,你没有遇到几个?

开发 后端
java 中有很多,新手经常遇到的陷阱,本文主要包含:自动装箱与拆箱;不可变的String;内存泄漏;自增类型使用;使用 “==”进行对象比较;double 类型计算

概述

 

[[280818]]

 

java 中有很多,新手经常遇到的陷阱,本文主要包含

  • 自动装箱与拆箱
  • 不可变的String
  • 内存泄漏
  • 自增类型使用
  • 使用 “==”进行对象比较
  • double 类型计算

不可变的String

Java String类是不可变的(不可修改)。这是因为String对象被缓存在String池中。字符串引用的对象可以更改,但字符串对象本身不能更改。

 

Java 中常见的几个陷阱,你没有遇到几个?

 

字符串是不可变的。一旦创建了字符串,以后将无法更改该字符串对象。

Java使用按值传递,而不是按引用传递。当您在方法中为分配新值时,它只会修改本地,而不是调用代码中的原始s

 

Java 中常见的几个陷阱,你没有遇到几个?

 

自动装箱与拆箱

装箱就是自动将基本数据类型转换为包装器类型;

拆箱就是自动将包装器类型转换为基本数据类型。

装箱拆箱的类型有哪些?

 

Java 中常见的几个陷阱,你没有遇到几个?

 

通过上图,可以看出,java 基本类型可以进行拆装箱。

那拆装箱会出现什么问题呢?

 

Java 中常见的几个陷阱,你没有遇到几个?

 

 

Java 中常见的几个陷阱,你没有遇到几个?

 

通过实例,上面两个程序,计算耗时相差近10倍,在大量存在装箱行为时,会导致程序性能低下。

当封装类型进行==、+、-、*、/计算时,会自动拆箱,对基础数据类型进行运算.所以在进行计算时,使用基本数据类型。

内存泄漏

Java的核心优势之一是 Java垃圾收集器,它可以管理堆上的对象内存。每当对象不可访问时,它将自动释放。

但是,对于新手和有经验的程序员而言,常见的错误是通过允许不再使用的对象可访问来防止释放内存。这可能对项目造成很大的不利影响,因为内存泄漏会阻塞资源并降低应用程序性能。它甚至可能导致java.lang.OutOfMemoryError。

常见的情况是:

  • 静态字段声明。静态字段,并在不再需要其数据后忘记将其设置为null
  • 未正常关闭流。 Java虚拟机为每个打开的连接分配内存。忘记关闭连接会消耗内存。这样的连接可以是:输入流,数据库连接,会话等。
  • finalize() 方法。当我们覆盖的finalize()方法,finalize()只会在对象内存回收前被调用一次,具有不确定行,只保证方法会调用,但不保证方法里的任务会被执行完。所以尽量避免使用。在Java 9 中,已经声明为过期函数,

自增类型使用

Java中运算符的计算顺序是在同等级下从左到右计算,看下自增情况

 

Java 中常见的几个陷阱,你没有遇到几个?

 

第一种情况的执行上下文如下:

1.存储操作数的先前值。

2.增加值。

3.返回上一个值

第二种情况的执行上下文如下:

1.增加值。

2.存储操作数的值(递增)

3.返回值

使用 “==”进行对象比较

许多新手程序员尝试使用“ ==”运算符比较对象,并且当代码的行为不符合预期时,就会感到困惑。需要注意的是,关系运算符“ ==”正在进行引用比较,它检查两个对象是否都指向内存中的相同位置。使用 .equals()方法将消除此问题,因为它会比较对象内部的值。

 

Java 中常见的几个陷阱,你没有遇到几个?

 

尽管有时“ ==”运算符会给出预期的答案:

 

Java 中常见的几个陷阱,你没有遇到几个?

 

这是什么原因呢?同样是字符串,创建的方式不同,差距咋这么大呢

Java语言规范的字符串文字中:同一包中不同类内的文字字符串表示对同一String 对象的引用

如果还不清楚那看下两种字符串创建过程

第一种new的方式

new一个字符串时,做了两件事。首先在堆中生成了该字符串对象,然后去看常量池中有没有该字符串,如果有就不管了,没有就往常量池中添加一个

 

Java 中常见的几个陷阱,你没有遇到几个?

 

第二种,直接赋值

这样创建字符串,首先会去常量池里找有没有这个字符串,有就直接指向常量池的该字符串,没有就先往常量池中添加一个,再指向它。

 

Java 中常见的几个陷阱,你没有遇到几个?

 

上面就是两种方式的对比情况了。

 

[[280822]]

 

两个Integer 对比

 

Java 中常见的几个陷阱,你没有遇到几个?

 

那为什么100的时候就是相等200就不行了呢这是由于Integer 使用了缓存。

 

Java 中常见的几个陷阱,你没有遇到几个?

 

其static块中就一次性生成了-128到127直接的Integer类型变量存储在cache[]中,对于-128到127之间的int类型,返回的都是同一个Integer类型对象。

整个工作过程就是:Integer.class在装载(Java虚拟机启动)时,其内部类型IntegerCache的static块即开始执行,实例化并暂存数值在-128到127之间的Integer类型对象。

当自动装箱int型值在-128到127之间时,即直接返回IntegerCache中暂存的Integer类型对象。

为什么Java这么设计?应该是出于效率考虑,因为自动装箱经常遇到,尤其是小数值的自动装箱;而如果每次自动装箱都触发new,在堆中分配内存,就太耗时了;

其它几种基本类型包装类,也进行了缓存

 

Java 中常见的几个陷阱,你没有遇到几个?

 

Double 类型计算

 

Java 中常见的几个陷阱,你没有遇到几个?

 

Java中的double和float在内部表示为二进制分数,因此在表示十进制分数时可能不够精确(IEEE标准754)。十进制数计算需要精度,需要使用java.math.BigDecimal

总结

Java 中还有很多小陷阱,如果你有可以写出来吆。

责任编辑:华轩 来源: 今日头条
相关推荐

2022-05-24 16:09:38

前端脚本

2020-08-13 06:43:41

React前端开发

2022-04-06 07:32:41

Java运算符变量

2019-08-29 09:15:30

负载均衡算法备份

2022-07-20 09:06:27

Hook封装工具库

2021-10-12 00:04:24

脚本备份MariDB

2022-07-03 23:26:38

DOMHook封装

2023-04-11 08:49:42

排序函数SQL

2014-05-04 16:39:49

开源项目开源产品

2022-06-30 08:31:54

排序函数SQL

2010-11-01 09:16:13

DIV+CSS

2010-10-26 10:16:36

求职

2010-01-26 15:32:43

Scala用法错误

2021-11-04 11:54:30

Linux内存系统

2022-11-16 09:04:36

SQL查询SELECT

2021-11-26 05:50:50

Promise JS项目

2023-12-06 14:23:24

2019-10-17 16:02:44

高并发缓存浏览器

2019-01-07 14:36:36

Go系统开源库

2021-10-18 06:54:47

Go开源库业务
点赞
收藏

51CTO技术栈公众号