JNI和Java在调用Integer.valueOf(int)时有不同的结果,这是一个bug吗?

JNI和Java在调用Integer.valueOf(int)时有不同的结果,这是一个bug吗?,java,integer,java-native-interface,Java,Integer,Java Native Interface,蚀 Visual Studio Integer v1 = Integer.valueOf(55); Integer v2 = Integer.valueOf(55); System.out.println("v1==v2 ? " + (v1 == v2)); //bacause of Integer cache, v1 == v2 is true v1=0x0000000019b01000{…} v2=0x0000000019b01008{…} 显然,v1和v2不是同一个对象。有人能告诉我为什

Visual Studio

Integer v1 = Integer.valueOf(55);
Integer v2 = Integer.valueOf(55);
System.out.println("v1==v2 ? " + (v1 == v2));
//bacause of Integer cache, v1 == v2 is true
v1=0x0000000019b01000{…} v2=0x0000000019b01008{…}
显然,v1和v2不是同一个对象。有人能告诉我为什么吗?谢谢在Java中使用
Integer.valueOf()
方法时,您正在创建Integer的实例,它是一个基本类型的包装器:
int

您已经知道上面的方法缓存值。如果您查看文档,您可以找到

返回表示指定int值的整数实例。如果不需要新的整数实例,通常应优先使用此方法而不是构造函数整数(int),因为此方法通过缓存频繁请求的值,可能会产生显著更好的空间和时间性能。此方法将始终缓存-128到127(含)范围内的值,并且可能缓存此范围之外的其他值

所以

jclass Integer = jni_env->FindClass("java/lang/Integer");
jmethodID valueOf = jni_env->GetStaticMethodID(Integer, valueOf", "(I)Ljava/lang/Integer;");
jint intV = 55;
jobject v1= jni_env->CallStaticObjectMethod(Integer, valueOf, intV);
jobject v2 = jni_env->CallStaticObjectMethod(Integer, valueOf, intV);
将评估为真实。但是在这里,使用
==
完成的操作不是对值本身,而是对堆内存中对象的引用。由于
.valueOf()自动缓存55,v1和v2指向同一个对象

将jni与以下调用一起使用时

Integer v1 = Integer.valueOf(55);
Integer v2 = Integer.valueOf(55);
System.out.println("v1==v2 ? " + (v1 == v2));

然后,
v1
是一个围绕java对象的jni对象。如果对
v2
执行相同的调用,则会得到不同的jni对象。两个对象都有不同的引用,但在内部将指向同一个整数对象。这就是您所看到的。

版本是JDK1.8.0您到底在打印什么来获取v1和v2的值?这可能只是这两个变量堆栈上的地址吗?(我知道我可能对JNI类型表现出可怕的无知…)是的,
jobject
是指向
struct\u jobject
的不透明指针。通过阅读
jni.h
,您可以看到这一点。也许我找到了原因。正如@KarelG所说,在vs中,v1和v2只是jni对象,内部对象是相同的<代码>*(无符号长*)0x0000000019d0b660
*(无符号长*)0x0000000019d0b668
具有相同的值0x802a2bf8,这证明它没有明显的区别。它到底在哪里说引用同一底层Java对象的两个不同的
jobject
应该具有相同的值?
jobject v1= jni_env->CallStaticObjectMethod(Integer, valueOf, intV);