Does Java have a using statement?

JavaHibernateUsing Statement

Java Problem Overview


Does Java have a using statement that can be used when opening a session in hibernate?

In C# it is something like:

using (var session = new Session())
{


}

So the object goes out of scope and closes automatically.

Java Solutions


Solution 1 - Java

Java 7 introduced Automatic Resource Block Management which brings this feature to the Java platform. Prior versions of Java didn't have anything resembling using.

As an example, you can use any variable implementing java.lang.AutoCloseable in the following way:

try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
    ...
}

Java's java.io.Closeable interface, implemented by streams, automagically extends AutoCloseable, so you can already use streams in a try block the same way you would use them in a C# using block. This is equivalent to C#'s using.

As of version 5.0, Hibernate Sessions implement AutoCloseable and can be auto-closed in ARM blocks. In previous versions of Hibernate Session did not implement AutoCloseable. So you'll need to be on Hibernate >= 5.0 in order to use this feature.

Solution 2 - Java

Before Java 7, there was no such feature in Java (for Java 7 and up see Asaph's answer regarding ARM).

You needed to do it manually and it was 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 limit 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.

Solution 3 - Java

Since Java 7 it does: http://blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec

The syntax for the code in the question would be:

try (Session session = new Session())
{
  // do stuff
}

Note that Session needs to implement AutoClosable or one of its (many) sub-interfaces.

Solution 4 - Java

Technically:

DisposableObject d = null;
try {
    d = new DisposableObject(); 
}
finally {
    if (d != null) {
        d.Dispose();
    }
}

Solution 5 - Java

The closest java equivalent is

AwesomeClass hooray = new AwesomeClass();
try{
    // Great code
} finally {
    hooray.dispose(); // or .close(), etc.
}

Solution 6 - Java

As of now, no.

However there is a proposal of ARM for Java 7.

Solution 7 - Java

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);
    }
  }
}

Solution 8 - Java

No, Java has no using statement equivalent.

Solution 9 - Java

In java 8 you can use try. Please refer to following page. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Solution 10 - Java

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.

Solution 11 - Java

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.

Solution 12 - Java

To answer the question regarding limiting scope of a variable, instead of talking about automatically closing/disposing variables.

In Java you can define closed, anonymous scopes using curly brackets. It's extremely simple.

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

The variable hooray is only available in this scope, and not outside it.

This can be useful if you have repeating variables which are only temporary.

For example, each with index. Just like the item variable is closed over the for loop (i.e., is only available inside it), the index variable is closed over the anonymous scope.

// first loop
{
    Integer index = -1;
    for (Object item : things) {index += 1;
        // ... item, index
    }
}

// second loop
{
    Integer index = -1;
    for (Object item : stuff) {index += 1;
        // ... item, index
    }
}

I also use this sometimes if you don't have a for loop to provide variable scope, but you want to use generic variable names.

{
    User user = new User();
    user.setId(0);
    user.setName("Andy Green");
    user.setEmail("[email protected]");
    users.add(user);
}

{
    User user = new User();
    user.setId(1);
    user.setName("Rachel Blue");
    user.setEmail("[email protected]");
    users.add(user);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmrblahView Question on Stackoverflow
Solution 1 - JavaAsaphView Answer on Stackoverflow
Solution 2 - JavaJoachim SauerView Answer on Stackoverflow
Solution 3 - JavariwiView Answer on Stackoverflow
Solution 4 - JavaChaosPandionView Answer on Stackoverflow
Solution 5 - JavaMichael BorgwardtView Answer on Stackoverflow
Solution 6 - JavamissingfaktorView Answer on Stackoverflow
Solution 7 - JavaAdam PaynterView Answer on Stackoverflow
Solution 8 - JavaRich AdamsView Answer on Stackoverflow
Solution 9 - Javauser232343View Answer on Stackoverflow
Solution 10 - JavaWill MarcouillerView Answer on Stackoverflow
Solution 11 - JavakrockView Answer on Stackoverflow
Solution 12 - JavaAlexView Answer on Stackoverflow