W C# mamy using, czyli taką konstrukcję, która przypomina trochę żonę – kurę domową (zakładając, że program to małżeństwo, a programista to mąż). Maż idzie do kibla robi swoje i zapomina wywołać close na desce. Żona samodzielnie zamknie deskę i nie będzie marudzić.
W Javie żona ma inne podejście. Nic nie mówi i nic nie robi. Po prostu jak raz na pewien czas z kibla będzie ulatniać się smród ponieważ nie zamknięto deski to maż w końcu nauczy się, żeby deskę opuszczać (nazywamy to tresurą małżeńską). Tu rolę gderającej i przypominającej o opuszczeniu deski teściowej pełnią narzędzia do sprawdzania poprawności kodu. Tak jak teściową zapraszamy do siebie raz na pewien czas tak i raz na pewien czas kod warto przepuścić przez findbuga, checkstyle czy PMD.
W Scali można zrobić jeszcze ciekawszą rzecz. Otóż o ile nie ma using to można sobie je napisać (za Beginning Scala D. Pollaka):

Listing 1. Definicja using w Scali

object Using{
    def using[A <: a="" b="" close="" unit=""> B): B = {
       try{ 
          f(param)
       } finally {
          param.close();
       }
    }
}</:>

I później użyć w kodzie:

Listing 2. Użycie using w Scali

using(statement.executeQuery("select * from dual")){ resultSet =>{
     // reszta kodu
  }
}

Taka konstrukcja przypomina żonę, która okazjonalnie zamknie deskę (o ile będzie w pobliżu czytaj mąż użyje using).
Generalnie w tym przypadku definiujemy funkcję, która jako parametr przyjmuje obiekt klasy, w której zdefiniowano metodę close() i dodatkowo przyjmuje jako drugi element coś, nazwane f co dokonuje transformacji A na B. To jest znany z Pythona tzw. „Duck Typing” (Jeżeli coś chodzi jak kaczka i kwacze jak kaczka to jest to kaczka – wnioskowanie typu na podstawie bebechów).

Jak widać konstrukcja jest fajna i przydatna. Zatem można by spróbować przenieść ją bezpośrednio do Javy (to też jest tresura małżeńska). Oczywiście jest to zabawka, której używanie w kodzie produkcyjnym jest średnio rozważne… ale niema ryzyka nie ma zabawy. Najwyżej się coś wywali.

Listing 3. Definicja using w Javie

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Emulator <b>using</b> ze Scali czy C#.
 * 
 * @author bartlomiejk
 * 
 */
public class Using {

	/**
	 * Wykonuje operacje z body poczym wywołuje <samp>close()</samp> z t.
	 * 
	 * @param <t>
	 *            typ generyczny z metodą <samp>close()</samp>
	 * @param t
	 *            zasób.
	 * @param body
	 *            operacja do wykonania.
	 * @throws RuntimeException
	 *             w dwóch przypadkach:
	 *             <ul>
	 *             <li>Brak metody <samp>close()</samp>.</li>
	 *             <li>Security Manager niepozwala na wywołanie metody <samp>close</samp>.</li>
	 *             </ul>
	 */
	public static <t> void using(T t, Unit<t> body) throws RuntimeException {
		Class extends Object> tClass = t.getClass();
		try {
			Method method = tClass.getMethod("close");
			method.setAccessible(true);
			try {
				body.perform(t);
			} finally {
				method.invoke(t);
			}
		} catch (SecurityException e) {
			throw new RuntimeException(e);
		} catch (NoSuchMethodException e) {
			throw new RuntimeException(e);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Synchronizowana wersja {@link #using(Object, Unit)}. synchronizacja względem zasobu.
	 * 
	 * @see Using#using(Object, Unit)
	 * 
	 * @param <t>
	 *            typ generyczny z metodą <samp>close()</samp>
	 * @param t
	 *            zasób.
	 * @param body
	 *            operacja do wykonania.
	 * @throws RuntimeException
	 *             w dwóch przypadkach:
	 *             <ul>
	 *             <li>Brak metody <samp>close</samp>.</li>
	 *             <li>Security Manager niepozwala na wywołanie metody <samp>close</samp>.</li>
	 *             </ul>
	 */
	public static <t> void s_using(T t, Unit<t> body) {
		synchronized (t) {
			using(t, body);
		}
	}

	/**
	 * Interfejs jednostki kodu wywołanej w ramach <samp>try</samp>/<samp>finally</samp>.
	 * 
	 * @author bartlomiejk
	 * 
	 * @param <t>
	 *            typ generyczny wykorzystywanego zasobu.
	 */
	public interface Unit<t> {
		/**
		 * Wywoływana jednostka kodu.
		 * 
		 * @param t
		 *            zasób.
		 */
		public void perform(T t);
	}
}</t></t></t></t></t></t></t></t>

Metoda using występuje też w synchronizowanej wersji s\_using, a muteksem jest zasób. Do wykorzystania z zasobami wymagającymi synchronizacji np. plikami.

Listing 4. Użycie using w Javie

using(daoSupport.executeQuery(CACHE_SQL), new Unit<resultset>() {               
	@Override                                                                   
	public void perform(ResultSet t) {                                          
		try {                                                                   
			while (t.next()) {                                                  
				//...   
			}                                                                   
		} catch (Exception e) {                                                 
			throw new RuntimeException(e);                                      
		}                                                                       
	}                                                                           
});</resultset>

To tyle. Raz jeszcze kod jest ciekawostkowy, niedopracowany i pewno coś będzie wywalał. Zatem używacie na własne ryzyko. Licencja beerware.