当我学习java时,我了解到比较2个字符串的正确方法是使用equals而不是“==”。这条线
static String s1 = "a";
static String s2 = "a";
System.out.println(s1 == s2);
将输出 true,因为 jvm 似乎已经优化了这段代码,以便它们实际上指向相同的地址。我试图用我在这里找到的一篇很棒的帖子来证明这一点
http://javapapers.com/core-java/address-of-a-java-object/ http://javapapers.com/core-java/address-of-a-java-object/
但地址似乎不一样。我缺少什么?
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class SomeClass {
static String s1 = "a";
static String s2 = "a";
public static void main (String args[]) throws Exception {
System.out.println(s1 == s2); //true
Unsafe unsafe = getUnsafeInstance();
Field s1Field = SomeClass.class.getDeclaredField("s1");
System.out.println(unsafe.staticFieldOffset(s1Field)); //600
Field s2Field = SomeClass.class.getDeclaredField("s2");
System.out.println(unsafe.staticFieldOffset(s2Field)); //604
}
private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}
}
我想你对什么感到困惑staticFieldOffset
正在返回。它返回的偏移量pointer to the String
实例,而不是地址String
本身。因为有两个字段,所以它们有不同的偏移量:即两个指针,它们恰好具有相同的值。
仔细阅读不安全的javadoc http://www.docjar.com/docs/api/sun/misc/Unsafe.html#staticFieldOffset%28Field%29显示这个:
报告给定字段在其存储分配中的位置
班级。不要期望对此执行任何类型的算术运算
抵消;它只是一个传递到不安全堆内存的 cookie
访问器。
换句话说,如果您知道实际的位置Class
实例在内存中,那么您可以将此方法返回的偏移量添加到该基地址,结果将是内存中可以找到指向实例的指针值的位置String
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)