java – String s1 == String s2(true)但是FieldOffset不同

前端之家收集整理的这篇文章主要介绍了java – String s1 == String s2(true)但是FieldOffset不同前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
当我正在学习 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/

但地址似乎不一样.我失踪了什么

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);
    }
}

解决方法

你没有丢失任何东西不安全的图书馆正在报告实际发生的情况.

字节码:

static {};
  Code:
   0:   ldc #11; //String a
   2:   putstatic   #13; //Field s1:Ljava/lang/String;
   5:   ldc #11; //String a
   7:   putstatic   #15; //Field s2:Ljava/lang/String;
   10:  return

注意,这两个字符串都放在内存中的不同位置,13和15.

这些变量存储在内存中,哪个需要一个单独的地址,以及一个新的对象是否放在堆上是有区别的.在这种情况下,它会为两个变量分配两个单独的地址,但它不需要创建一个新的String对象,因为它识别同一个String文字.所以这两个变量都引用同一个字符串.

如果你想得到地址,你可以使用这个问题How can I get the memory location of a object in java?中的答案.确保您在使用前阅读注意事项,但我做了一个快速测试,似乎工作.

猜你在找的Java相关文章