Java 为什么这两种获取布尔值的方法会有不同的结果?

Java 为什么这两种获取布尔值的方法会有不同的结果?,java,jvm,unsafe,Java,Jvm,Unsafe,我写了代码: public class StaticBooleanDemo { private static boolean flag; public static boolean getFlag(){ return flag; } public static void main (String[] args ) throws Exception{ Unsafe unsafe = MyJVMUtil.getUnsafe(); Field field =

我写了代码:

public class StaticBooleanDemo {
  private static boolean flag;

  public static boolean getFlag(){
    return flag;
  }

  public static void main (String[] args ) throws Exception{
    Unsafe unsafe = MyJVMUtil.getUnsafe();
    Field field = StaticBooleanDemo.class.getDeclaredField("flag");
    unsafe.putInt(StaticBooleanDemo.class,
    unsafe.staticFieldOffset(field),2);
    System.out.println("getFlag():"+getFlag());
    System.out.println("flag:"+flag);

  } 

}
我得到了两个结果,第一个是假的,第二个是真的。我很困惑,想知道为什么变量标志有两种不同的结果? 但是当我在两个IDE中运行它时,它也会给出不同的结果,第一个是在eclipse中,第二个是在idea中。

首先,您使用的是不安全行为,顾名思义,这不是一件安全的事情-因此,当您看到这样的问题时,您不应该依赖这种行为

您可能看到的是两个IDE之间的编译器或JVM的不同。您正在编写一个Int值(4字节),即使这样也只能工作,因为它是在一个小的endian机器上运行的,因为第一个字节是非零值所在的位置。这样做可能会破坏堆上的下一个值

假设布尔值的表示不受语言的严格限制,那么可能是一个编译器正在为“is it zero”生成字节码,而另一个编译器正在查看低阶位,这取决于它是否被设置;i、 e.
x!=0
x&1
可以给出您描述的行为

我建议先使用
javap
查看生成的字节码在第一个实例中是什么样子,然后检查是否在同一个JVM中运行它们


但最后的建议是,不要使用不安全的,尤其不要通过写入超过字段所需的数据来覆盖堆上的数据。

注释不用于扩展讨论;这段对话已经结束。
public class MyJVMUtil {
   public static Unsafe getUnsafe(){
    try {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        Unsafe unsafe = (Unsafe) field.get(null);
        return unsafe;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}
}