19

I've an object with a certain state. The object is passed around and it's state is temporarly altered. Something like:

public void doSomething(MyObject obj) {
    obj.saveState();
    obj.changeState(...);
    obj.use();
    obj.loadState();
}

In C++ it's possible to use the scope of an object to run some code when constructing and distructing, like

NeatManager(MyObject obj) { obj.saveState(); }
~NeatManager() { obj.loadState(); }

and call it like

void doSomething(MyObject obj) {
    NeatManager mng(obj);
    obj.changeState();
    obj.use();
}

This simplifies the work, because the save/load is binded with the scope of NeatManager object. Is it possible to do something like this in Java? Is there a way to call a method when the object goes out of the scope it's been declared in? I'm not talking about finalize() nor "destruction" (garbage collection), I'm interested on the scope.

Thanks

Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
AkiRoss
  • 11,745
  • 6
  • 59
  • 86

5 Answers5

13

Nope, there's no such thing. The closest is probably a try/finally block:

try
{
    obj.changeState(...);
    obj.use();
}
finally
{
    obj.loadState();
}

This ensures that loadState() gets called even when an Exception is thrown or there's an early return.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
5

No, there's nothing like that. The closest you've got is try/finally.

In C# there's the using statement, which executes a Dispose method at the end:

using (Stream x = ...)
{
} // x.Dispose() is called here, in a finally block

There's a possibility that Java 7 will gain something a bit like this, but I don't think anything's been set in stone yet.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

Java 7 has try-with-resources and you can extend AutoCloseable class to make use of it.

For Java 6 you may want to see the related question: What is the best way to emulate try-with-resources in Java 6?

Wernight
  • 36,122
  • 25
  • 118
  • 131
2

As an additional note, don't be tempted to use the Object.finalize() method, which runs when an object is GC'd, as you have no control over when the object is collected.

Steve B.
  • 55,454
  • 12
  • 93
  • 132
0

Short answer: No.

Medium answer: The best practice in this situation is to use a try ... finally block.

Longer answer: C++ doesn't really give you this either: C++ destructors are run on de-allocation. If you fail to deallocate an object and all references to it fall out of scope, the destructor will not be called.

As an aside, if garbage collection in Java was reference counting, then finalizers would implement exactly this behaviour.

jwoolard
  • 6,024
  • 9
  • 37
  • 37
  • 9
    In fact, C++ does support exactly what the OP was asking about. –  Jan 22 '10 at 14:23
  • 1
    I don't understand why you say that in the long answer. I thought that all objects where distructed after the function is done, as the stack is freed from all the allocated objects. Also, I'm pretty sure that this is a Good Practice, as I read about it on GOTW, but I'm not sure and I shall check. Edit: not sure if it was GotW, Exceptional C++ or More exceptional C++ :\ – AkiRoss Jan 22 '10 at 14:43
  • 1
    True, C++ destructors will be called on stack-allocated objects when the stack that references them is deallocated. However, on heap allocated objects (i.e. the vast majority of objects on most programs), the destructor will only be called on explicit destruction using the `delete` keyword. – jwoolard Jan 25 '10 at 09:17
  • 3
    In C++, local objects like this tend to be stack allocated. You do not put something on the heap using the `new` keyword unless you want to manage the object's lifecycle yourself. Stack allocated objects are destructed the moment the object goes out of scope. – Chris Betti May 25 '15 at 23:02