如果一个对象是同一类的实例,它们的大小相同,我可以使用 sun.misc.Unsafe 覆盖另一个对象吗?
编辑: “覆盖”是指“删除”第一个对象,用第二个对象填充内存。可能吗?
最佳答案
By "override" I mean to "delete" first object, ant to fill the memory with the second one. Is it possible?
是也不是。
是 - 如果您使用 Unsafe 分配一些内存并写入 long ,然后在其中写入另一个 long (例如),那么是的,您已经删除了第一个对象并用第二个对象填充了内存。这类似于您可以使用 ByteBuffer 执行的操作.当然,long 是原始类型,因此它可能不是您所说的“对象”。
Java 允许这样做,因为它可以控制分配的内存。
否 - Java 使用对对象的引用并仅提供对这些对象的引用。此外,它倾向于在内存中移动对象(即,用于垃圾收集)。
没有办法获取“物理地址”并将内存内容从一个对象地址移动到另一个对象地址,如果您正在尝试这样做的话。此外,您实际上无法“删除”该对象,因为它可能在代码的其他地方被引用。
但是,总是有可能通过 A = objectB;
将 A 指向另一个 objectB 而不是 objectA;您甚至可以使用 Unsafe.compareAndSwapObject(... )
。
解决方法 - 现在,假设引用 A1、A2、A3 指向同一个对象 A。如果你想让它们都突然指向objectB,你不能使用Unsafe.compareAndSwapObject(...)
,因为只有A1会指向objectB,而A2和A3仍然会指向objectA .它不会是原子的。
有一个解决方法:
public class AtomicReferenceChange {
public static Object myReference = new Object();
public static void changeObject(Object newObject) {
myReference = newObject;
}
public static void main(String[] args) {
System.out.println(AtomicReferenceChange.myReference);
AtomicReferenceChange.changeObject("333");
System.out.println(AtomicReferenceChange.myReference);
}
}
您可以定义一个公共(public)静态引用,并让您的代码在任何地方都使用 AtomicReferenceChange.myReference
,而不是对同一个对象有多个引用。如果您想以原子方式更改引用的对象,请使用静态方法 changeObject(...)
。
关于java - 我可以用 sun.misc.Unsafe 覆盖对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6042858/