การลบวัตถุใน java?


101

ฉันต้องการลบวัตถุที่ฉันสร้างขึ้น (วงรีที่ตามหลังคุณ) แต่ฉันจะทำอย่างไร

delete follower1;

ไม่ได้ผล

แก้ไข:

โอเคฉันจะให้บริบทเพิ่มเติม ฉันกำลังสร้างเกมเล็ก ๆ ที่มีวงรีที่คุณสามารถควบคุมได้และวงรีที่ติดตามคุณ ตอนนี้ฉันมีไฟล์ที่ชื่อ DrawPanel.class คลาสนี้ดึงทุกอย่างบนหน้าจอและจัดการการชนกันเสียง ฯลฯ ฉันได้รับคลาสศัตรูซึ่งเป็นวงรีตามผู้เล่น ฉันได้เอนทิตี้คลาสซึ่งเป็นผู้เล่นที่คุณสามารถควบคุมได้ และถ้าผู้เล่นตัดกับผู้ติดตามฉันต้องการให้วัตถุเครื่องเล่นของฉันถูกลบ วิธีที่ฉันทำ:

    public void checkCollisions(){
    if(player.getBounds().intersects(follower1.getBounds())){
        Follower1Alive = false;
        player.health = player.health - 10;
    }
}

1
คุณสามารถระบุบริบทเพิ่มเติมได้ไหม
Joseph Weissman

2
ไม่มีการลบวัตถุใน Java แต่โดยปกติคุณไม่จำเป็นต้องทำสิ่งที่คุณต้องการคือตรวจสอบให้แน่ใจว่าไม่มีอะไรแสดงที่หน้าจออีกต่อไป (หากนี่คือสิ่งที่ "ติดตามคุณ" กำลังทำอยู่)
Paŭlo Ebermann

บางทีคุณอาจต้องการลองบังคับให้คนเก็บขยะเอาวัตถุออก? มีคำถามเกี่ยวกับเรื่องนี้ที่นี่อยู่แล้ว หรือบางทีคุณอาจลองทำอย่างอื่น? คุณสามารถลองอ่านข้อมูลเกี่ยวกับที่เก็บขยะได้ที่นี่หรือที่นี่หากยังไม่สามารถช่วยได้คุณจะต้องเจาะจงมากขึ้น
Fawix


หากคุณต้องการจัดการการจัดสรรอ็อบเจ็กต์ด้วยตนเองจริงๆให้ใช้ JNI: สร้าง C / C ++ lib ซึ่งใช้จากโค้ด Java แต่ทำทุกอย่าง (สร้างลบ ฯลฯ ) ด้วยตัวเอง - แต่ภายใน lib คุณมี C / รหัส C ++ ไม่มี Java ฉันไม่เห็นวิธีใดในการลบวัตถุ Java ด้วยตนเอง หากผู้สร้างโปรไฟล์ของคุณแจ้งว่ามีปัญหาปัญหาเหล่านี้มักขึ้นอยู่กับการอ้างอิง "ลืม" ไปยังวัตถุ ในกรณีของคุณดูเหมือนจะไม่มีปัญหาใด ๆ
Johannes

คำตอบ:


178

คุณควรลบการอ้างอิงถึงมันโดยกำหนด null หรือออกจากบล็อกที่มีการประกาศ หลังจากนั้นเครื่องเก็บขยะจะถูกลบโดยอัตโนมัติ (ไม่ใช่ในทันที แต่ในที่สุด)

ตัวอย่างที่ 1:

Object a = new Object();
a = null; // after this, if there is no reference to the object,
          // it will be deleted by the garbage collector

ตัวอย่างที่ 2:

if (something) {
    Object o = new Object(); 
} // as you leave the block, the reference is deleted.
  // Later on, the garbage collector will delete the object itself.

ไม่ใช่สิ่งที่คุณกำลังมองหา แต่ FYI: คุณสามารถเรียกใช้ตัวเก็บขยะด้วยการเรียกSystem.gc ()


24
System.gc()โดยทั่วไปแล้วการโทรด้วยตนเองไม่ใช่ความคิดที่ดีเนื่องจาก JVM อาจละเลยไป
cdeange

3
ไม่ใช่ความคิดที่ดี แต่คุณสามารถเรียกคล้ายกับ System .. Runtime.getRuntime (). gc () ข้อมูลเพิ่มเติม: รูทีนการรวบรวมขยะที่ Java จัดเตรียมให้เป็นสมาชิกของคลาส Runtime คลาส Runtime เป็นคลาสพิเศษที่มีอ็อบเจ็กต์เดียว (a Singleton) สำหรับแต่ละโปรแกรมหลัก วัตถุ Runtime จัดเตรียมกลไกสำหรับการสื่อสารโดยตรงกับเครื่องเสมือน ในการรับอินสแตนซ์ Runtime คุณสามารถใช้เมธอด Runtime.getRuntime () ซึ่งส่งคืน Singleton
Timo

1
การnullมอบหมายเป็นสัญญาณที่ชัดเจนสำหรับ GC ว่าวัตถุนี้จะถูก Garbaged Cleaned ในการเรียกใช้ GC ครั้งต่อไปnullหรือไม่ stackoverflow.com/questions/449409/…
George Daramouskas

ดังนั้นฉันควรทำให้ textviews และ imagebuttons ทั้งหมดเป็นโมฆะในonPause?
Ruchir Baronia

ไม่มีการรับประกันว่าตัวเก็บรวบรวมขยะจะเคยทำงานหรือไม่ก็จะรวบรวม (ไม่ใช่ 'ลบ') วัตถุเฉพาะใด ๆ
Marquis of Lorne

65

C ++ ของคุณกำลังแสดง

ไม่มีdeleteใน java และอ็อบเจ็กต์ทั้งหมดถูกสร้างขึ้นบนฮีป JVM มีตัวรวบรวมขยะที่อาศัยการนับอ้างอิง

เมื่อไม่มีการอ้างอิงถึงอ็อบเจ็กต์อีกต่อไปผู้รวบรวมขยะจะพร้อมใช้งานสำหรับการรวบรวม

myObject = nullไม่อาจทำได้ ตัวอย่างเช่น:

Foo myObject = new Foo(); // 1 reference
Foo myOtherObject = myObject; // 2 references
myObject = null; // 1 reference

ทั้งหมดนี้ตั้งค่าการอ้างอิงmyObjectเป็นโมฆะไม่มีผลต่อวัตถุmyObjectเมื่อชี้ไปยกเว้นเพียงแค่ลดจำนวนการอ้างอิงลง 1 เนื่องจากmyOtherObjectยังคงอ้างถึงวัตถุนั้นจึงยังไม่สามารถรวบรวมได้


ดังนั้นฉันควรทำให้ textviews และ imagebuttons ทั้งหมดเป็นโมฆะในonPause?
Ruchir Baronia

8
"JVM มีตัวเก็บขยะที่อาศัยการนับอ้างอิง" -> นั่นเป็นคำอธิบายที่ง่ายมาก ตรวจสอบว่าวัตถุสามารถเข้าถึงได้จาก "รูท" ที่เฉพาะเจาะจงหรือไม่
Johannes

2
JVM มีตัวรวบรวมขยะที่ไม่ต้องพึ่งพาการนับอ้างอิงโดยเฉพาะ มันขึ้นอยู่กับความสามารถในการเข้าถึง หากมันขึ้นอยู่กับการนับการอ้างอิงก็จะไม่สามารถรวบรวมรอบได้และทำได้
Marquis of Lorne

14

หากคุณต้องการช่วยให้วัตถุหายไปให้ตั้งค่าการอ้างอิงเป็น null

String x = "sadfasdfasd";
// do stuff
x = null;

การตั้งค่าการอ้างอิงเป็น null จะทำให้มีโอกาสมากขึ้นที่วัตถุจะถูกเก็บรวบรวมตราบเท่าที่ไม่มีการอ้างอิงอื่น ๆ ไปยังวัตถุ


เมื่อใดก็ตามที่ฉันทำเช่นนั้นเมื่อวัตถุของฉันตัดกันเกมทั้งหมดของฉันจะหยุดและจะไม่ลบวัตถุนั้น
สแตน

เนื่องจากคุณอาจใช้ข้อยกเว้นของตัวชี้โมฆะที่ไม่ถูกจับ บริบทเพิ่มเติมจะช่วยให้เราแนะนำคุณได้อย่างแน่นอน
Joseph Weissman

ดังนั้นฉันควรทำให้ textviews และ imagebuttons ทั้งหมดเป็นโมฆะในonPause?
Ruchir Baronia

หากคุณต้องการให้พวกเขาจากไปจริงๆก็จะทำได้ในที่สุด
John Percival Hackworth

3

คุณไม่จำเป็นต้องลบวัตถุใน java เมื่อไม่มีการอ้างอิงถึงวัตถุเครื่องเก็บขยะจะถูกรวบรวมโดยอัตโนมัติ


ดังนั้นฉันควรทำให้ textviews และ imagebuttons ทั้งหมดเป็นโมฆะในonPause?
Ruchir Baronia

0

คุณสามารถลบข้อมูลอ้างอิงโดยใช้null.

สมมติว่าคุณมีคลาสA:

A a = new A();
a=null;

คำสั่งสุดท้ายจะลบการอ้างอิงของวัตถุ aและวัตถุนั้นจะถูก "เก็บรวบรวมขยะ" โดย JVM เป็นวิธีที่ง่ายที่สุดวิธีหนึ่ง


ดังนั้นฉันควรทำให้ textviews และ imagebuttons ทั้งหมดเป็นโมฆะในonPause?
Ruchir Baronia

-3

ใช่ java เป็น Garbage ที่รวบรวมไว้มันจะลบความทรงจำสำหรับคุณ


37
ในช่วงเวลาที่คาดหวังน้อยที่สุด
matcheek

2
s / ลบ / รั่ว / g
Mark K Cowan

-6
//Just use a List
//create the list
public final List<Object> myObjects;

//instantiate the list
myObjects = new ArrayList<Object>();

//add objects to the list
Object object = myObject;
myObjects.add(object);

//remove the object calling this method if you have more than 1 objects still works with 1
//object too.

private void removeObject(){
int len = myObjects.size();
for(int i = 0;i<len; i++){
Objects object = myObjects.get(i);
myObjects.remove(object);
}
}

เหตุผลที่คำตอบนี้ไม่ถูกต้องเป็นเพราะเพียงลบการอ้างอิงไปยังวัตถุไม่ใช่วัตถุจริง
Ben Morris

สาเหตุที่คำตอบนี้ไม่ถูกต้องเนื่องจากแสดงให้เห็นว่าคุณสามารถลบวัตถุออกจากรายการได้อย่างไร - นี่ไม่ใช่คำถาม
phil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.