0

As per my understanding of the below code snippet, the Car object will become eligible for GC after line no. 12. But the given solution says it will not. Can anyone check the below link and correct me if I am wrong?

01: var rl = new ArrayList<Repairable>();
02: var car = new Car();
03: var clutch = car.getClutch();
04: var engine = (Repairable) null;
05: rl.add(car);
06: rl.add(clutch);
07: car = null;
08: clutch = null;
09: rl.add(engine);
10: rl.set(2, engine);
11: rl.remove(0);
12: rl.remove(1);

https://blogs.oracle.com/javamagazine/post/java-quiz-object-reachability

Update: The article says "Car object will not become eligible for GC even after line 12."

I am not agreeing especially on this line. At index 1, the value is not null it actually holds the clutch object

Line 12 removes the item at index 1, which is the null. The list, therefore, contains nothing except the clutch.

user3966432
  • 378
  • 3
  • 15
  • 4
    Could you clarify which part of the articles explanation you don't understand? It seems to sum it up concisely: _"the Clutch object itself, which is an inner class, contains a reference to its enclosing instance, which is the Car object. Because of that reference, the Car object is still reachable after line 12"_ – Brian61354270 Aug 09 '23 at 17:18
  • 2
    Also, please note that questions on Stack Overflow _must be self contained_. It's OK to link that article as a reference, but your question must be understandable and answerable without accessing it. Please [edit] your question to include all of the essential parts, and/or reduce it to a [mre] of the part that you're asking about – Brian61354270 Aug 09 '23 at 17:20
  • Thanks @Brian61354270. As suggested updated the question. – user3966432 Aug 09 '23 at 17:30
  • 1
    Could you clarify what you think the contents of `rl` is at lines 10, 11, and 12? I think you may be either missing the fact that line 11 shifted the elements in the list, or are thinking that index 1 means the first element when it really means the second. Lines 11 and 12 together removes the elements that were at indices 0 and 2 as of line 10. – Brian61354270 Aug 09 '23 at 17:35
  • 1
    after line 11, the clutch is at index 0; index 1 holds `null` that was added as index 2, but line 11 removed the first element (`remove(0)`), so now `null` is at index 1 – user16320675 Aug 09 '23 at 17:37
  • 2
    Before line 11: `[car, clutch, null]`, after line 11: `[clutch, null]`, `remove(1)` removes the `null` and the final list is `[clutch]`. – Kayaman Aug 09 '23 at 17:49
  • You are right Brian61354270, user16320675, and kayaman I was missing the point that line no. 11 would shift all upper indexes – user3966432 Aug 09 '23 at 17:53
  • And for the future: Even after your edit, your code doesn't compile and is missing vital information to answer the question (the fact that Clutch is a non-static inner class). Again, please read [mre]. – Sören Aug 09 '23 at 18:49

1 Answers1

2

You have missed that the first call to remove shifts the indexes of the other elements. remove(1) on line 12 removes the null; clutch is still in the array, and clutch contains a reference to the Car because it is nonstatic.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • 2
    Note that starting with JDK 18 the `Clutch` object [will not keep a reference to its outer (`Car`) object anymore](https://bugs.openjdk.org/browse/JDK-8271717). This demonstrates (again) that quiz questions around non-observable behavior are bad. Mandatory read: [Can java finalize an object when it is still in scope?](https://stackoverflow.com/q/24376768/2711488) – Holger Aug 21 '23 at 12:05