Java的值类型和引用类型
一、问题描述
前几天因为一个需求出现了Bug。说高级点也挺高级,说白点也很简单。其实也就是一个很简单的Java基础入门时候的值类型和引用类型的区别。只是开发的时候由于自己的问题,导致小问题的出现。还好突然想起来以前看过一篇对于该问题讲解的博客,才能快速定位问题的位置。防止下次再犯,顺便也就把这个当做笔记记录下来,放入自己的Bug集中。
二、值类型和引用类型的比较
这个大家应该都是没问题的,很简单。值类型比较是比较值,引用类型是比较地址。对于正常的操作来说,比较值类型我们可以直接使用 == ,引用类型就使用equals来做比较就不会出现问题。
引用类型
/**
* 测试Integer
*/
public static void test_Integer(){
Integer number_01 = 10;
Integer number_02 = 10;
System.out.println(number_01.equals(number_02));
}
上面的测试结果很明显是true,绝对没有问题的。

值类型
/**
* 测试int
*/
public static void test_Int(){
int number_01 = 10;
int number_02 = 10;
System.out.println(number_01 == number_02);
}
上面的测试结果很明显是true,绝对没有问题的。

三、问题
但是问题就出现在,开发的使用为了防止出现为null的时候会被系统使用0来代替,所以就使用了Integer类型来做操作,并且在比较的时候用了 == 。这就很尴尬了,开始自测完全没出现问题,因为没到达记录数。很开心,把代码提交下班,妥妥的。但是尴尬的事情来了,测试报告出现在了邮箱里面了。
初始没问题的情况
/**
* 测试Integer
*/
public static void test_Integer(){
Integer number_001 = 10;
Integer number_002 = 10;
System.out.println(number_001 == number_002);
}
结果:

当记录超过一定数的时候,出现问题
/**
* 测试Integer
*/
public static void test_Integer(){
Integer number_001 = 128;
Integer number_002 = 128;
System.out.println(number_001 == number_002);
}
结果:

四、解决
后面一想,很快确定问题了。是自己的马虎,偷懒使用了 == ,造成这次问题的出现,当改为equals就可以妥妥的回家了。开始自测没问题主要还是因为Integer 的缓存搞的事情。扒拉到Integer的源码,发现里面用了缓存机制,对-128~127的值做了缓存,如果在这个值区间内使用==来做比较的话,比较的就是值了,所以才造成开始以为没问题,后面运行了一段时间后就出现问题了。当不在值区间内就必须使用equals来完成比较。
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
五、总结
当初面试的时候这种东西应该是背的滚瓜烂熟,绝对可以应对面试。但是一旦开发起来就是各种问题都出现了,而且这种东西还不会报出错日志,纯属开发问题。归总来说还是自己的水平不够,还需要继续提高。下次要防止这种低级问题的出现,很尴尬。同样也是对自己学的东西要融汇贯通,而不是每学一个单独的知识点就够了,没有起到联通的效果。源码扒拉一下还是会加深自己的印象。
Java的值类型和引用类型的更多相关文章
- JAVA中值类型和引用类型的不同(面试常考)
转载:https://www.cnblogs.com/1ming/p/5227944.html 1. JAVA中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个 ...
- java中值类型和引用类型的区别
[定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是传入的变量的值也将改变. 值类型表示复制一个当前变量传给方法,当你 ...
- java中值类型与引用类型的关系
值类型:就是java的基本类型.byte.short.int.long.float.char.double.boolean 引用类型:类(class).接口(Interface).数组(Array) ...
- 学习记录 java 值类型和引用类型的知识
1. Java中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变 ...
- JAVA初学(1):值类型和引用类型的区别
JAVA值类型和引用类型的区别(转) [定义] 引用类型表示你操作的数据是同一个,也就 ...
- JAVA值类型和引用类型的区别
java这两种数据类型分别有哪些? java 中的数据类型分为两大类:值类型(基本数据类型)和引用类型(复合数据类型) 一:值类型: 整数类型(byte,short,int,long) 浮点类 ...
- java和c#值类型和引用类型
java数据类型分为基本数据类型和引用类型 基本数据类型:int float double bool char byte 引用数据类型:string array class interfa ...
- C# 值类型和引用类型及参数传递
值类型和引用类型: C#数据类型分为两大类:值类型和引用类型. 值类型数据主要有:结构体struct,枚举体enum,布尔型bool,浮点型,整型. 引用类型数据主要有:数组,字符串,接口,委托,类. ...
- go语言关于值类型和引用类型
前言:关于值类型和引用类型确实是个比较绕的问题,之前在学校的时候学习C语言的时候,就感觉没有看太懂,后面看java,关于引用也是模模糊糊,这个东西也确实比较抽象,估计好多写了好几年代码的人有也有些迷惑 ...
随机推荐
- HTML——基础知识点1
- 平滑启动shell脚本
# 平滑关闭和启动 Spring Boot 程序#设置端口SERVER_PORT="8090"#当前时间time=`date +%Y-%m-%d`#设置应用名称JAR_NAME=& ...
- springboot返回统一接口与统一异常处理
springboot返回统一接口与统一异常处理 编写人员:yls 编写时间:2019-9-19 0001-springboot返回统一接口与统一异常处理 简介 创建统一的返回格式 Result 封装统 ...
- Idea集成SpringBoot实现两种热部署方式(亲测有效)
即将介绍的两种热部署方式: 1.SpringLoaded 2.DevTools 区别: SpringLoader:SpringLoader 在部署项目时使用的是热部署的方式. DevTools:Dev ...
- Python print函数使用
本文链接:https://www.cnblogs.com/zyuanlbj/p/11905405.html 函数定义 def print(self, *args, sep=' ', end='\n', ...
- (二十九)golang--map
map:是key-value数据结构,又称为字段或者关联数组,类似其它编程语言的集合: 基本语法:var 名称 map[键类型]值类型 key的类型可以是:bool.数字.string.指针.管道,还 ...
- expect 自动填充密码
它的脚本以#!/usr/bin/expect开头,执行时用expoct,而不是bash.我的一个给samba自动创建用户并且自动填写默认密码的脚本如下: vim smb_passwd.exp #!/u ...
- systemd概念和运行机制
systemd概念 核心概念:单元 依赖关系 systemd事务 启动目标和运行级别 单元 早期CentOS版本中的服务管理脚本在CentOS7中被服务但源文件替换.系统初始化需要启动后台服务,需要完 ...
- goland_beego框架学习--api实现
goland_beego框架学习--api实现 完成一项api实现的流程 (1)beego框架的router层里面注册路由 正则路由 为了用户更加方便的路由设置,beego 参考了 sinatra 的 ...
- 扛把子组20191017-8 alpha week 2/2 Scrum立会报告+燃尽图 07
此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9804 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩昊 ...