Question

I've seen reference in some C# posted questions to a "using" clause. Does java have the equivalent?

Was it helpful?

Solution

Yes. Java 1.7 introduced the try-with-resources construct allowing you to write:

try(InputStream is1 = new FileInputStream("/tmp/foo");
    InputStream is2 =  new FileInputStream("/tmp/bar")) {
         /* do stuff with is1 and is2 */
}

... just like a using statement.

Unfortunately, before Java 1.7, Java programmers were forced to use try{ ... } finally { ... }. In Java 1.6:

InputStream is1 = new FileInputStream("/tmp/foo");
try{

    InputStream is2 =  new FileInputStream("/tmp/bar");
    try{
         /* do stuff with is1 and is 2 */

    } finally {
        is2.close();
    }
} finally {
    is1.close();
}

OTHER TIPS

Yes, since Java 7 you can rewrite:

InputStream is1 = new FileInputStream("/tmp/foo");
try{

    InputStream is2 =  new FileInputStream("/tmp/bar");
    try{
         /* do stuff with is1 and is2 */

    } finally {
        is2.close();
    }
} finally {
    is1.close();
}

As

try(InputStream is1 = new FileInputStream("/tmp/foo");
    InputStream is2 =  new FileInputStream("/tmp/bar")) {
         /* do stuff with is1 and is2 */
}

The objects passed as parameters to the try statement should implement java.lang.AutoCloseable.Have a look at the official docs.

For older versions of Java checkout this answer and this answer.

The nearest equivalent within the language is to use try-finally.

using (InputStream in as FileInputStream("myfile")) {
    ... use in ...
}

becomes

final InputStream in = FileInputStream("myfile");
try {
    ... use in ...
} finally {
    in.close();
}

Note the general form is always:

acquire;
try {
    use;
} finally {
    release;
}

If acquisition is within the try block, you will release in the case that the acquisition fails. In some cases you might be able to hack around with unnecessary code (typically testing for null in the above example), but in the case of, say, ReentrantLock bad things will happen.

If you're doing the same thing often, you can use the "execute around" idiom. Unfortunately Java's syntax is verbose, so there is a lot of bolier plate.

fileInput("myfile", new FileInput<Void>() {
   public Void read(InputStream in) throws IOException {
       ... use in ...
       return null;
   }
});

where

public static <T> T fileInput(FileInput<T> handler) throws IOException {
    final InputStream in = FileInputStream("myfile");
    try {
        handler.read(in);
    } finally {
        in.close();
    }
}

More complicated example my, for instance, wrap exceptions.

Not that I'm aware of. You can somewhat simulate with a try...finally block, but it's still not quite the same.

The closest you can get in Java is try/finally. Also, Java does not provide an implicit Disposable type.

C#: scoping the variable outside a using block

public class X : System.IDisposable {

    public void Dispose() {
        System.Console.WriteLine("dispose");
    }

    private static void Demo() {
        X x = new X();
        using(x) {
            int i = 1;
            i = i/0;
        }
    }

    public static void Main(System.String[] args) {
        try {
            Demo();
        } catch (System.DivideByZeroException) {}
    }

}

Java: scoping the variable outside a block

public class X {

    public void dispose() {
        System.out.println("dispose");
    }

    private static void demo() {
        X x = new X();
        try {
            int i = 1 / 0;
        } finally {
            x.dispose();
        }        
    }

    public static void main(String[] args) {
        try {
            demo();
        } catch(ArithmeticException e) {}
    }

}

C#: scoping the variable inside a block

public class X : System.IDisposable {

    public void Dispose() {
        System.Console.WriteLine("dispose");
    }

    private static void Demo() {
        using(X x = new X()) {
            int i = 1;
            i = i/0;
        }
    }

    public static void Main(System.String[] args) {
        try {
            Demo();
        } catch (System.DivideByZeroException) {}
    }

}

Java: scoping the variable inside a block

public class X {

    public void dispose() {
        System.out.println("dispose");
    }

    private static void demo() {
        {
            X x = new X();
            try {
                int i = 1 / 0;
            } finally {
                x.dispose();
            }
        }
    }

    public static void main(String[] args) {
        try {
            demo();
        } catch(ArithmeticException e) {}
    }

}

It was a long time coming but with Java 7 the try-with-resources statement was added, along with the AutoCloseable interface.

I think you can achieve something similar to the "using" block, implementing an anonymous inner class. Like Spring does with the "Dao Templates".

Well, using was syntactic sugar anyway so Java fellows, don't sweat it.

If we get BGGA closures in Java, this would also open up for similar structures in Java. Gafter has used this example in his slides, for example:

withLock(lock) { //closure }

The actual idiom used by most programmers for the first example is this:

InputStream is1 = null;
InputStream is2 = null;
try{
    is1 = new FileInputStream("/tmp/bar");
    is2 = new FileInputStream("/tmp/foo");

    /* do stuff with is1 and is 2 */

} finally {
    if (is1 != null) {
        is1.close();
    }
    if (is2 != null) {
        is2.close();
    }
}

There is less indenting using this idiom, which becomes even more important when you have more then 2 resources to cleanup.

Also, you can add a catch clause to the structure that will deal with the new FileStream()'s throwing an exception if you need it to. In the first example you would have to have another enclosing try/catch block if you wanted to do this.

No there isn't.

You can

public void func(){

  {
    ArrayList l  =  new ArrayList();
  }
  System.out.println("Hello");

}

This gives you the limited scope of the using clause, but there isn't any IDisposable interface to call finalization code. You can use try{}catch(){}Finally{}, but it doesn't have the sugar of using. Incidentally using finalizers in Java is generally a bad idea.

No, there is no using in Java, the most similar functionality is the "import" keyword.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top