2010-11-23 55 views
2


我不知道如何删除其他方法中的对象,例如我想删除deleteObject方法中的dog对象,但它只是删除当前对象的引用! 有没有解决方法?如何在Java中使用其他方法删除对象?

public class Main { 
    public static void main(String[] args) { 
     Dog dog = new Dog("Max"); 
     deleteObject(dog); 
     System.out.println(dog.toString()); //it still exists! I want to remove it 
    } 

    public static void deleteObject(Dog dog) { 
      dog = null; //I want to remove this object but it deletes just this method's reference 
    } 
} 

class Dog { 
    private String name; 

    public Dog(String name) { 
     this.name=name; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 
+0

使狗成为一个全局变量,它会正常工作。但我建议你可以使用单例模式,如果你需要更好地使用对象。 – zengr 2010-11-23 09:32:30

+0

你是什么意思是“删除”? - 释放内存? – Ralph 2010-11-23 09:38:11

+0

全局是静态变量?如果我尝试静态狗狗;它仍然没有工作。我试图使用signletone模式,但在我的应用程序中,它并不是最好的决定,因为它使用多线程 – gennad 2010-11-23 09:39:53

回答

2

在Java对象是通过GC垃圾回收(在字中删除)。当不存在有效的参考到该对象是自动化的过程。此外,你不能100%确定,当没有裁判存在它已被删除其正义请求。

0
public class Main { 
    static Dog dog = null; 
    public static void main(String[] args) { 

     dog = new Dog("Max"); 
     dog = deleteObject(dog); //really unnecessary 

     if(dog==null) 
     { 
      System.out.println("I AM DEAD!"); 
     } 
     else 
     { 
      System.out.println(dog.toString()); 
     } 
    } 

    public static Dog deleteObject(Dog dog) { 
     dog = null; 

     return dog; 
    } 
} 


class Dog { 
    private String name; 

    public Dog(String name) { 
     this.name=name; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 
} 
2

当没有更多引用时,对象被“删除”(或者更具体地说,有资格被垃圾收集器删除)。在你的例子中有两个引用指向同一个对象(你的主要方法中的狗引用和deleteObject方法中的狗引用)。当您在deleteObject中将狗设置为null时,main中的狗引用仍然指向该对象。

您可以将主引用中的狗引用设置为null,这将使对象成为垃圾回收的可用对象。或者让狗引用一个类变量,即在任何方法外部声明 - 然后main和delteObject可以使用相同的狗引用。

为什么你想要删除对象呢?在方法结束时,无论如何所有本地引用都会超出范围,并且该对象将变为垃圾收集的可用范围。

1

我有一个解决方案,但也许这对您的问题太过矫枉过正;它涉及到在WeakReferences:

public class Pound{ 
    public static WeakReference<Dog> adopt(String name){ 
     Dog newDog = new Dog(name); 
     dogList.add(newDog); 
     return new WeakReference<Dog>(newDog); 
    } 

    public static void sacrifice(WeakReference<Dog> dogRef){ 
     Dog sadPuppy = dogRef.get(); 
     dogList.remove(sadPuppy); 
    } 

    private static List<Dog> dogList = new ArrayList<Dog>(); 

    public class Dog{ 
     public String getName(){ 
     return this.name; 
     } 

     private Dog(String name){ 
     this.name = name; 
     } 

     private String name; 
    } 
} 

这里的关键是要确保到狗情况下是唯一的强引用是在磅级(或有一种方法本地引用),并使用在WeakReferences其他地方。这样,当你调用方法

sacrifice(WeakReference<Dog> dog) 
从任何地方

在你的代码,你会被删除的唯一强引用它,使它符合使用GC。所以,如果你想从任何方法处置狗实例:

class Main{ 
    public static void main(String ... args){ 
     WeakReference<Dog> max = Pound.adopt("Max"); 

     //This line prints "Max" 
     System.out.println(max.get().getName()); 
     meanMethod(max); 

     //Max is now dead, so you get a NullPointerException 
     System.out.println(max.get.getName()); 
    } 

    public static void meanMethod(WeakReference<Dog> dog){ 
     Pound.sacrifice(dog); 
     //From this point, dog is no more ='(
    } 
} 

您可以在一个方法创建狗的实例,而在另一个处置这些,只要你只有一个永久的强引用(在列出存放狗的位置),并提供方法将它们从列表中添加和删除。当然,如果你这样做,这是没有用的:

Dog strongDog = weakReferenceToDog.get(); 

在你的主要方法。

此外,您必须在代码的每个部分对使用get()的空值进行检查,并且需要一些方法来持续清理包含死亡WeakReferences的ReferenceQueue。

根据你实际打算做的事情,这可能太多了,你会更好地用另一种解决方案,或完全忘记这一点,但至少这是我能想到的唯一办法可以工作。

相关问题