原始值如何存储在对象中以及在对象被转换时会发生什么

Luk*_*cek 1 java primitive integer

这是一个非常基本的问题我猜,但我不知道如何不遵守所以如果有人会这么善良

Object a = 128;
Object b = 128;
Log.debug("a: " + ((Integer) a == (Integer)b));
Log.debug("b: " + (((Integer) a).intValue() == ((Integer) b).intValue()));
Run Code Online (Sandbox Code Playgroud)

"a"为假而"b"为真,a = 127且b = 127均为真

JB *_*zet 7

Object a = 128
Run Code Online (Sandbox Code Playgroud)

被编译为

Object a = Integer.valueOf(128)
Run Code Online (Sandbox Code Playgroud)

这称为自动装箱.

在某些JDK版本中,Integer.valueOf()使用通常从-128到127的Integer实例缓存,并从此缓存返回实例,而不是每次都创建一个新的Integer实例.这就是为什么==127返回true而不是128返回true 的原因.

不要依赖于此,因为它是非强制性的实现细节.始终比较它们的原始int值或使用equals().


Per*_*ror 5

==运算符仅适用于整数实例的缓存值.并且整数的缓存范围是-128到127.然而,在第二种情况下,Integer.intValue()返回一个int原语,在这种情况下,==运算符在原语的情况下工作.

有关:

后增量后==的令人费解的行为


T.J*_*der 5

当您比较对象引用时,==定义为true引用引用同一对象时,而不是等效对象.(那equals是为了什么.)

对于基元,==定义true为等效值.

在第一个示例中,您有两个不同的对象,一个分配给a另一个,另一个分配给b.这是因为您尝试分配给引用类型的原语是"autoboxed"(自动包装在原语的等效对象类型中).你的代码:

Object a = 128;
Object b = 128;
Run Code Online (Sandbox Code Playgroud)

......实际上是这样对待的:

Object a = Integer.valueOf(128);
Object b = Integer.valueOf(128);
Run Code Online (Sandbox Code Playgroud)

... Integer.valueOf返回一个Integer包装你给它的值的对象,对于后续具有相同值的调用,它可能是也可能不是同一个对象,具体取决于你给它的值.来自Javadoc:

如果Integer不需要新实例,则通常应优先使用此方法,而不是构造函数Integer(int),因为此方法可能通过缓存频繁请求的值来显着提高空间和时间性能.此方法将始终缓存-128到127(包括端点)范围内的值,并可以缓存此范围之外的其他值.

所以这意味着当你使用值127运行它时,每次调用都会得到相同的对象Integer.valueOf,因此==工作正常.但对于128,每次调用都会返回不同的对象,因此==无法工作,因为它再次检查两个引用是否引用同一个对象,而不是等效对象.