tags:

views:

375

answers:

6

In Java is there an equivalent to the C# "using" statement allowing to define a scope for an object:

using (AwesomeClass hooray = new AwesomeClass())
{
   // Great code
}

This has probably already been asked but the keywords make it difficult to find a relevant question.

+8  A: 

No, there's no such feature in Java.

You need to do it manually and it is a pain:

AwesomeClass hooray = null;
try {
  hooray = new AwesomeClass();
  // Great code
} finally {
  if (hooray!=null) {
    hooray.close();
  }
}

And that's just the code when neither // Great code nor hooray.close() can throw any exceptions.

If you really only want to limite the scope of a variable, then a simple code block does the job:

{
  AwesomeClass hooray = new AwesomeClass();
  // Great code
}

But that's probably not what you meant.

Joachim Sauer
Your Java equivalent should be no problem if `// Great code` throws an exception.
Cheeso
When the constructor throws an exception, I think your code is going to result in a NullPointerException that masks the original exception.
Michael Borgwardt
@Michael: actually my example would not compile, because `horray` may not have been initialized at that point (fixed now).
Joachim Sauer
+1 for floating simple blocks being able to limit scope. However, whenever I see these it's almost always an indicator that the method should be broken up into smaller chunks.
Mark Peters
+2  A: 

The closest java equivalent is

AwesomeClass hooray = new AwesomeClass();
try{
    // Great code
} finally {
    hooray.dispose(); // or .close(), etc.
}
Michael Borgwardt
+20  A: 

It is not there yet. Have a bit of patience, it will come in Java 7 as "Automatic Resource Block Management" using the try keyword. E.g.

try (BufferedReader br = new BufferedReader(new FileReader(path)) {
   return br.readLine();
}

See also:

BalusC
+1  A: 

Please see this List of Java Keywords.

  1. The using keyword is unfortunately not part of the list.
  2. And there is also no equivalence of the C# using keyword through any other keyword as for now in Java.

To imitate such "using" behaviour, you will have to use a try...catch...finally block, where you would dispose of the resources within finally.

Will Marcouiller
The fact that `using` is not a keyword doesn't mean a thing. The same feature can be (and will be!) implemented with another keyword, as @BalusC mentioned.
Joachim Sauer
I agree! But for now, it doesn't exist, right? That is what the OP asked, if there was something alike just now. It is good to know that it will exists in future releases, but that doesn't change a thing as for now, one way or another. Anyway, the information provided by @BalusC is great though! =)
Will Marcouiller
I agree with that, but your post seems to say that the fact that `using` is not in the list of Java keywords means that this feature is not present in the Java language. And that's not true.
Joachim Sauer
If this is what my post seems to say, then I will edit to reflect my intention.
Will Marcouiller
I edited my answer specifying that there was no `using` keyword, and neither any equivalence as for now. Thanks @Joachim Sauer! =)
Will Marcouiller
A: 

ARM blocks, from project coin will be in Java 7. This is feature is intended to bring similar functionality to Java as the .Net using syntax.

krock
+2  A: 

If you're interested in resource management, Project Lombok offers the @Cleanup annotation. Taken directly from their site:

You can use @Cleanup to ensure a given resource is automatically cleaned up before the code execution path exits your current scope. You do this by annotating any local variable declaration with the @Cleanup annotation like so:

@Cleanup InputStream in = new FileInputStream("some/file");

As a result, at the end of the scope you're in, in.close() is called. This call is guaranteed to run by way of a try/finally construct. Look at the example below to see how this works.

If the type of object you'd like to cleanup does not have a close() method, but some other no-argument method, you can specify the name of this method like so:

@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);

By default, the cleanup method is presumed to be close(). A cleanup method that takes argument cannot be called via @Cleanup.

Vanilla Java

import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    InputStream in = new FileInputStream(args[0]);
    try {
      OutputStream out = new FileOutputStream(args[1]);
      try {
        byte[] b = new byte[10000];
        while (true) {
          int r = in.read(b);
          if (r == -1) break;
          out.write(b, 0, r);
        }
      } finally {
        out.close();
      }
    } finally {
      in.close();
    }
  }
}

With Lombok

import lombok.Cleanup;
import java.io.*;

public class CleanupExample {
  public static void main(String[] args) throws IOException {
    @Cleanup InputStream in = new FileInputStream(args[0]);
    @Cleanup OutputStream out = new FileOutputStream(args[1]);
    byte[] b = new byte[10000];
    while (true) {
      int r = in.read(b);
      if (r == -1) break;
      out.write(b, 0, r);
    }
  }
}
Adam Paynter