19

C# supports disposable pattern for deterministic garbage collection using the dispose pattern.

Is there such pattern for java?

Java 7 has autoclosable, which you can use with try finally blocks to invoke the close method.

What about versions prior to 7?

Is there a disposable pattern (deterministic garbage collection) for Java 5 or 6?

sdgfsdh
  • 33,689
  • 26
  • 132
  • 245
DarthVader
  • 52,984
  • 76
  • 209
  • 300
  • 2
    I'm afraid, no, you must do it manually. – Vlad Oct 14 '11 at 21:43
  • 2
    The AutoCloseable has no impact on Garbage collection. What it does is ensure resources are clean up correctly. Are you sure the C# pattern has any effect on the GC? – Peter Lawrey Oct 14 '11 at 21:48
  • 4
    I just wanted to point out that neither C#'s `using` nor Java 7's `try`-with-resources pattern offer deterministic *garbage collection*. They offer deterministic *resource control*. I know I'm being pedantic about it, but it's an important difference. – Randolpho Oct 14 '11 at 21:49
  • 1
    @PeterLawrey looks like we cross-posted the same thing. C# is just like Java's; there's no real effect on the GC by default, although some patterns (particularly Microsoft's own suggested pattern) recommend suppressing finalization -- the first step in garbage collection. Regardless, the object memory is not reclaimed immediately. – Randolpho Oct 14 '11 at 21:51

3 Answers3

22

The closest prior to Java 7 is just "manual" try/finally blocks:

FileInputStream input = new FileInputStream(...);
try {
  // Use input
} finally {
  input.close();
}

The using statement was one of the things I found nicest about C# when I first started using C# 1.0 from a Java background. It's good to see it finally in Java 7 :)

You should also consider Closeables in Guava - it allows you to not worry about whether or not a reference is null (just like a using statement does) and optionally "logs and swallows" exceptions thrown when closing, to avoid any such exception from effectively "overwriting" an exception thrown from the try block.

James Moore
  • 8,636
  • 5
  • 71
  • 90
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Doesn't that potentially leak a resource? Wouldn't it be better to initialize `input` to `null` outside the `try` and to construct the `FileInputStream` inside the `try`. Then in the `finally` check for a non-`null` instance and close it. (I am pretty sure it needs to be initialized to `null` outside the `try` because otherwise assignment cannot be guaranteed.) – Noel Widmer Dec 21 '17 at 16:02
  • @NoelWidmer: If an asynchronous exception could occur between the assignment and entering the `try` block, then the same exception could presumably occur after the constructor completes but before the resulting reference is assigned to the `input` variable. But in Java at least, I don't believe that's an issue. – Jon Skeet Dec 21 '17 at 16:05
  • @JonSkeet You're right. (Although I don't know if async could be an issue in Java) – Noel Widmer Dec 21 '17 at 16:12
  • @Noel: By asynchronous exceptions, I mean exceptions that can be thrown at entirely arbitrary points. – Jon Skeet Dec 21 '17 at 16:13
  • @JonSkeet I know what you meant. Those nasty beasts are the reason I commented initially. – Noel Widmer Dec 21 '17 at 16:14
6

The entire purpose of the disposal pattern is to support C#'s unique using (temporaryObject) pattern. Java has had nothing like that pattern before 7.

All Java objects that had resources supported the disposal pattern via manually closing the object that held resources.

Randolpho
  • 55,384
  • 17
  • 145
  • 179
  • 5
    I know its an old post, but for completeness its fair to say its the other way around. The whole purpose of `using` is to assure that disposable objects in local context are indeed disposed without requiring try/finally enclosure. Disposable pattern itself is used frequently outside of local context, and thus without `using`, especially if object disposed contains references to other disposable objects. – mmix Jun 14 '15 at 14:20
-1

What you are looking for is try with resources.

try ( FileInputStream input = new FileInputStream(...);
      BufferedReader br = new BufferedReader(...) ) {
  // Use input
} 

The resource has to be Closeable (or AutoCloseable), of course.

  • It is clear from the OPs question that he already knows about this, and that he is asking for how this could be done before Java 7... – SJuan76 Jun 14 '18 at 04:22