“==”和 java.lang 中默认的 equals 实现既然都是对于内存空间中地址的比较,那么为什么可以使用
i == 1
这样的写法来判断 i 和 1 是否相等呢?以前倒是从来没有考虑过这个问题,求教下 V 友。
1
ovear 2016-03-05 19:46:56 +08:00
i 是什么 Integer ? 基本类型可以
|
2
FinalDream 2016-03-05 19:51:54 +08:00
基本类型都在栈里
|
3
jsyangwenjie 2016-03-05 20:08:15 +08:00
基本类型
|
4
mikicomo OP |
5
ovear 2016-03-05 20:13:14 +08:00
@mikicomo 参见 Cache Pool , Java 在创建这些类型的对象的时候,内部有个表,如果不存在就创建,存在就直接指向。
还是比较内存地址。 |
6
mikicomo OP @ovear 哦哦,虽然暂时还不是很明白(琢磨着也不一定看得懂 Cach Pool ),但是 mark 了(果然是一个小细节都不能放过啊,以前很理所应当的 逻辑运算符号也有这么大的讲究,)
|
7
wmlhust 2016-03-05 21:48:13 +08:00
对于基本类型是直接比较值的吧
对于对象,默认的 equals 是比较引用指向的对象地址 |
8
SoloCompany 2016-03-05 22:01:52 +08:00 via iPad
基本类型和 object 完全是两个世界,==操作符的定义对于基本类型和 object 也是完全无关的
|
10
ovear 2016-03-06 14:10:36 +08:00
@otakustay 是 cache 关系,基本类型都是保证内存中有一个唯一实例。
但是包装类型可以有多个实例。 比如说 new Integer(1); 这个 Integer 本身是新的,但是内部指向的这个 基本类型 1 是唯一确定的。 |
11
otakustay 2016-03-06 19:59:30 +08:00
@ovear 你说的是 Integer ,这是一个 object 类型,而楼主表达的是 1 ,这是一个 primitive 类型。==操作符对这两类使用的逻辑是不同的, Integer 是引用比较,因为 cache 的原因一般都会成功,正如你说的;而 primitive 是内存值比较,和 cache 没有啥关系, int 在做==运算的时候也不会进行装箱转为 Interger
同时, Integer 的 cache 也并不可靠,你可以试试 Integer a = new Integer(12); Integer b = new Integer(12); System.out.println(a == b); 这并不会给你想要的结果 |
12
ovear 2016-03-06 20:51:25 +08:00
@otakustay 关于你说的这个问题,很明显你是没有理解好 Java 的 Cache Pool 以及 Java 的自动拆装箱
Integer a = 12; Integer b = 12; Integer c = new Integer(12); Integer d = 12; a==b==d c 和 abc 任意一个都不等 这个才是 cache pool ,建议你看一下相关资料,其他包装类型,包括 String 也有类似的机制 同时注意我上面的话 基本类型都是保证内存中有一个唯一实例。 而 包装类型 保证的是,默认情况下会使用同一个实例,但是你强制使用 new 来创建包装类型, Java 就会忽略 Cache ,直接帮你创建,但是包装类型内部指向的 基本类型 是一样的。 所以不管是基本类型,还是包装类型,比较的都是内存地址。只不过 Java 保证基本类型在内存中有唯一实例,才使得 == 操作符表现出来的行为像是值比较。 (如有错误欢迎指正) |
13
colincat 2016-03-06 21:56:15 +08:00 via iPhone
Intger i=100,如果整型字面量的值在-128 到 127 之间,那么不会 new 新的 Integer 对象,而是直接引用常量池中的 Integer 对象
|
14
otakustay 2016-03-07 11:24:46 +08:00
@ovear 我理解楼主说的是下面这个问题:
int i = 1; int j = 1; i == j; 这里和 Integer 一点关系也没有, Integer 怎么工作我自然知道。这里的 i 和 j 的内存地址不一样,甚至把 i 通过参数传给另一个函数地址也不同( pass by copy ),但它们可以通过==运算 |
15
otakustay 2016-03-07 11:26:55 +08:00
|
16
mikicomo OP |
17
ovear 2016-03-07 18:49:29 +08:00
@otakustay Long 并不是基础类型,另外多看文档,范围讲的很清楚。
http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7 @mikicomo @otakustay 如果是关于 int a = 1; int b = 1; 这两个基本类型的问题,我之前的理解有问题,之前不知道在哪本书和 zhihu 上看到了,对于基本类型也有个这种东西。但是经过 @大神 之后,证明我我的说法有问题。 基本类型不一定会具备内存地址,可能还会存在于寄存器当中。 http://blog.csdn.net/lm2302293/article/details/6713147 部分类型在 byte code 中是有常量的 如 0x02 iconst_m1 int 型常量值-1 进栈 0x03 iconst_0 int 型常量值 0 进栈 具体、更专业的说法参考 https://www.zhihu.com/question/26711836/answer/89610502 |