2011-05-18 116 views
9

我可以覆盖一个obejct与另一个,如果他们是同一类的实例,它们的大小是一样的,采用sun.misc.Unsafe?我可以用sun.misc.Unsafe覆盖对象吗?

编辑: 通过“越权”我的意思是“删除”第一个对象,蚂蚁,以填补第二个内存。可能吗?

+0

你是什么意思的“覆盖”?请提供更多背景。 – 2011-05-18 09:58:45

+1

我怀疑他想Smalltalk的一个Java版本[变成:(http://gbracha.blogspot.com/2009/07/miracle-of-become.html)。 – 2011-05-18 10:01:51

回答

9

“覆盖”我的意思是“删除”第一个对象,蚂蚁填充内存 与第二个。可能吗?

是和否。

- 如果分配与不安全的一些记忆,写long,然后写另一个长在它(例如),那么,你已经删除的第一个对象,并与第二物体填满记忆。这与ByteBuffer可以做的相似。当然,long是一个原始类型,所以它可能不是'object'的意思。

Java允许这一点,因为它有分配的内存控制。

- Java处理对象的引用,仅提供对这些对象的引用。此外,它倾向于在内存中移动对象(即,用于垃圾收集)。

有没有办法让“物理地址”,并从一个对象地址移到内存内容到另一个,如果这就是你想什么。而且,你实际上不能'删除'这个对象,因为它可能从代码中的其他地方被引用。

但是,总是有引用A指向另一个objectB而不是objectA的可能性A = objectB;您甚至可以使用Unsafe.compareAndSwapObject(...)这个原子。

解决方法 - 现在,让我们假设引用A1,A2,A3指向相同的objectA。如果你希望它们全部突然指向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); 

    } 

} 

而不必对同一个对象的多个引用的,你可以定义一个公共静态参考,让你的代码中使用AtomicReferenceChange.myReference无处不在。如果要以原子方式更改引用的对象,请使用静态方法changeObject(...)

+2

扩展这个解决方案,如果你有过问题的类控制你也许可以使用代理模式(http://en.wikipedia.org/wiki/Proxy_pattern)更优雅的解决这个问题。 代理类将提供所有方法的实际类,但它只会将它们委托给包装对象。客户不需要意识到他们是否正在使用代理,并且通过交换被包装的对象,您可以让他们看起来好像他们正在使用的对象已被替换。 – Medo42 2011-05-26 17:39:29

+0

所以,如果您有多个引用来“立即”修改,则代理模式肯定比多个静态变量更合适。在代理类中修改它比较容易... – JVerstry 2011-05-26 18:00:19