我的一个java对象,有好几个地方引用。比如 a、b、c、d四个引用都指向同一个对象。单纯a=null,另外几个b、c、d仍然不为null,对象还是不能被销毁。我的目的是销毁一个对象 ,并让它的所有引用都变成 null

解决方案 »

  1.   

    我不知道如何显式的销毁一个对象,但是你单纯的a=null,那肯定只是a会指向空对象;其他三个引用仍然是指向创建的那个对象.你要把所有引用都变成NULL,最主要的办法是如销毁那个对象.
      

  2.   

    可以利用弱引用对不使用的对象进行回收……
    import java.lang.ref.WeakReference;
    ……A a=new A();
    ……
    //使用完了a,将它设置为弱引用,并释放引用
    WeakReference wr=new WeakReference(a);
    a=null;
    ……
    //下次使用时
      if(wr!=null)
       {
        a=wr.get();
       }
      else
        {
          a=new A();
          wr=new WeakReference(a);
          
        }
      

  3.   

    其实我的目的是这样的 。比如我创建了一个对象放在了一个Arraylist中,但这个对象又在别的地方被引用。现在我把这个对象从Arraylist清除 ,如何保证别的引用处也知道这个对象被清除了。置为null是不行的,设标志字段也比较繁琐
      

  4.   


    我的意思是,一个对象在A、B两个地方被引用,在A地方的引用被置为null以后,B地方的引用仍不为null,怎么样让B地方的引用自动也为null?例如下例
    /////////////////////
    public class M {
    public static void main(String[] args) {
    SvgUse su = new SvgUse();
    AbsShape a = su.child;//a和su.child两个引用指向一个对象
    a = null;//a置为null
    System.out.println(su.child);//但su.child不为null
    System.out.println(a);//a为null
    }
    }class SvgUse {
    public AbsShape child = new AbsShape();
    }class AbsShape {
    }
      

  5.   

    那就把所有instance都放在一个池中, 集中管理。
      

  6.   

    系统小的话,我现在使用swing做一个较大的桌面软件。结构层次相当复杂,把所有的instance放一个池中不是不可以,而是改动较大
      

  7.   

    可以用标志字段的方式来解决这个问题,比如给AbsShape 一个字段表示不用了,但该类实际上需要序列化,影响序列化和反序列化
    class AbsShape { 
      boolean valid=true;

      

  8.   


    我知道,你使用一下弱引用,只要释放一处,所有的地方就都被释放了,如果你对弱引用不是很了解你可以去找一下相关资料了解一下弱引用与垃圾回收器的关系,我把你代码改下,你看看import java.lang.ref.WeakReference;
    public class M { 
    public static void main(String[] args) { 
    SvgUse su = new SvgUse(); 
    AbsShape a = su.child;//a和su.child两个引用指向一个对象 WeakReference wr=new WeakReference(a); a = null;//a置为null 
    System.out.println(su.child);//但su.child不为null 
    System.out.println(a);//a为null 

    } class SvgUse { 
    public AbsShape child = new AbsShape(); 
    } class AbsShape { 

      

  9.   

    销毁对象,和,引用为null是两回事,不要混为一谈.如果想要某个对象的所有引用都为null可以创建一个管理对象,记录所有的引用,当需要时,让所有的引用都为空,就可以了.例如,创建一个HashSet,当a要引用某个对象x时,将a放入HashSet,b要引用x时,将b放入HashSet.
    当你想把a,b都设为空时,迭代HashSet并赋值null就可以了.销毁对象,JVM会自动处理的,人工管理太麻烦.
    a对象存在一个唯一指向b对象的引用,b对象存在一个唯一指向x对象的应用,当b(或a)不再被引用时,x对象也会被垃圾回收的.关键是,程序员在使用集合类的时候,不要将太多的数据存放至集合对象(比如10万个数据放入HashSet),这样JVM内存会有可能暴掉.
      

  10.   

    Java里面不能强制销毁一个对象(只能通过把所有以指向它的引用设为null,调用System.gc()后,才有可能销毁),所以从理论上就不能实现。
      

  11.   

    其实我想大家在应用开发的时候都有过这种经历 。一个对象在a处创建了,但b处又需要引用它。这样就有了两个引用当在a处删除的时候 ,希望在b处也删除它;如果系统稍大的时候,可能多次引用的次数会更加多,一一删除很繁琐。有没有办法一处删除 ,别处也同时删除,至少把引用置为null,下次能识别出来
      

  12.   

    import java.lang.ref.WeakReference;public class M {
    public static void main(String[] args) {
    SvgUse su = new SvgUse();
    AbsShape a = su.child;//a和su.child两个引用指向一个对象 
    WeakReference wr = new WeakReference(a);
    a = null;//a置为null 
    System.out.println(su.child);//但su.child不为null 
    System.out.println(a);//a为null 
    }
    }class SvgUse {
    public AbsShape child = new AbsShape();
    }class AbsShape {
    }
    输出结果
    AbsShape@a90653
    null我希望的是两个输出都为null,至少能从su.child自身识别出它被删除了
      

  13.   

    Java把对象的生命周期交给JVM来管理,这事它的原则,也是它独特的处理方式,在使用这种方式的同时,也会引入一些问题,正如楼主遇到的这种情况。所以,我们在当初程序设计的时候,就应该考虑到这样的问题,而不是除了问题了,再去解决。可能楼主还是需要在类的设计和使用上花一点功夫,处理好类之间的引用和导航关系。不要让Java的优势成为枷锁。Good luck!
      

  14.   

    直接把所有指向某个对象的所有引用都置为null是不可能的,但是有变通的办法:
    使用一个包装器类,包裹你的对象,所有原先期望指向该对象的引用都换成指向该包装器对象(当然类型是不一样的)
    当需要使用实际的对象时,从包装器中将它取出,并保证用完之后不在程序的其他地方保持对实际对象的强引用
    当需要销毁时,将该包装器类的实际对象引用置为null,那么所有指向该包装器的引用将无法得到实际对象!
    通常使用jdk提供的4个引用等级的包装器是比较理想的
    你可以把你的系统设计成在某个位置保持实际对象的强引用,而当它不再有存在的必要时,将它置为null,那么它就有机会在JVM做垃圾回收时将它销毁
      

  15.   

    也可以考虑使用工厂模式,你说的a,b,c,d不要直接保存实际对象的引用,只需要引用工厂
    如果工厂认为应该向你提供对象,那么你就能得到,否则就返回一个null
    这两种策略都不可能在你的代码上透明过渡,都需要修改你的系统设计!
      

  16.   

    楼主这是在用 Java 吗?
      

  17.   

    用工厂方法获得引用的时候,还是要用一个标识 ,比如id什么的。而我们这个系统的id,根据客户的要求 ,都设计成 id1、id2、id3..这样连续的整数后缀,删除id2的时候,id3自动向前变成id2。其实还有一个办法,就是采用内部id,这个id是自增加,绝不会重复,展现给用户的是连续的id。
    但这样一来,系统的设计要做不小的改动
      

  18.   

    java都是自己销毁对象,没办法只有一个一个置空.
      

  19.   

    的确。
    可以看看Java Pitfalls一书中的介绍。
      

  20.   

    JAVA对象也有"指针",你可以置为空,但是不知道怎么删除,不是经过克隆的对象,只是简单的a=b的话,当引用对象改变时,被引用对象也会改变.
      

  21.   

    这两天仔细修改了,给每个对象添加了唯一不变的globalId。取得对象引用的时候都用get(String globalId),只在一个地方保留引用,别的地方只记录globalId。当get(globalId)返回为空就清除之。有些人的习惯是一个对象保持多处引用,这种方式虽然运行效率高些,但维护会很麻烦。如果只在一处保留引用,别处只保留globalId,用get方法或者工厂返回引用,返回后的引用不保留,用完就扔。 这种方式扩展性较好
      

  22.   

    楼主的这几个引用是不是要改变对象的值,如果不改变可以考虑用static对象
      

  23.   

    这个问题无解.
    所谓的弱引用,更是在搞笑.
    如果我要把一个变量传给一个方法,你弱给我看看.传给内部类,你弱给我看看.
    另外,如果我有三个变量都抓住这个对象的弱引用,当我释放其中一个另两个也自动释放?
    要解决这个问题除非拿到JDK源码,自己修改插入一个方法,setNull(Object o),
    然后把那个对地址空间的内容全部memreset为0.
    凭什么要求别人一定要采用你那根本不可行的方法,别人不采用就发怒?
      

  24.   

    我觉得不可能实现,不同的引用指向同一个对象,除了让所有的引用都指向null,才会消除这个对象。
      

  25.   

    import java.lang.ref.WeakReference; public class M { 
    public static void main(String[] args) { 
    SvgUse su = new SvgUse(); 
    AbsShape a = su.child;//a和su.child两个引用指向一个对象 
    WeakReference wr = new WeakReference(a); 
    a = null;//a置为null 
    System.out.println(su.child);//但su.child不为null 
    System.out.println(a);//a为null 

    } class SvgUse { 
    public AbsShape child = new AbsShape(); 
    } class AbsShape { 

    输出结果 
    AbsShape@a90653 
    null 

    我希望的是两个输出都为null,至少能从su.child自身识别出它被删除了 希望你用弱引用把上述代码修改一下,能使得
    两个输出都为null
      

  26.   

    哈哈,楼主说的不错,有本事用弱引用让一个为null时其它的都为null.
    有人在搞笑,还装很懂,说白了,这是不可能实现的,因为这是一个语法的原因:
    String s = "xxxx";
    String s1 = s;
    String s2 = s;
    无论你s指向什么,不可能在语句s = null时同时自动执行s1 = null;s2 = null;
    这不是说改变原来指向的结对象是什么,或以什么方式指向对象,而是同时执行三条重新赋值语句,
    和它们用什么方向指向对象以及原来对象是什么没有关系.对于这样的结果还说有解的话,到底是不是无知,那只能是公道自在人心了.
    就象说在算术运行的前提下,让1+1=1,我说无解,那么有解的人是无知还是有知?
      

  27.   

    我知道这个问题无解,但软件开发经常碰到此类问题,所以用什么样的设计模式变通解决此类问题是关键。只在一处保留引用,其余地方用工厂返回引用可以有效解决问题,但效率有些降低,每次都要在一个list或者hashtable中查找,确实效率不高。
      

  28.   

    你的设计有问题。
    不要保存引用,需要的时候使用一个函数获取所需的对象,这正是OO最基本的思想,如果要考虑效率问题的话根本就别用java了。
      

  29.   

    嗯嗯,java对象的销毁问题一直是一块心病