Есть ли в Java эквивалент выражения C using «using» - PullRequest
23 голосов
/ 26 сентября 2008

В некоторых опубликованных вопросах на C # я видел ссылку на предложение "using". Есть ли у Java эквивалент?

Ответы [ 12 ]

26 голосов
/ 26 сентября 2008

Да. В Java 1.7 появилась конструкция try-with-resources , позволяющая написать:

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

... точно так же как using заявление.

К сожалению, до Java 1.7 программисты на Java были вынуждены использовать try {...} finally {...}. В 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();
}
9 голосов
/ 21 сентября 2013

Да, начиная с Java 7 вы можете переписать:

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

как

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

Объекты, переданные в качестве параметров в оператор try, должны реализовывать java.lang.AutoCloseable. Посмотрите официальные документы .

Для более старых версий Java checkout этот ответ и этот ответ .

5 голосов
/ 27 сентября 2008

Ближайшим эквивалентом в языке является использование try-finally.

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

становится

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

Обратите внимание, что общая форма всегда:

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

Если приобретение находится в блоке try, вы разблокируете его в случае сбоя при получении. В некоторых случаях вы можете взломать ненужный код (обычно тестирование на ноль в приведенном выше примере), но в случае, скажем, ReentrantLock произойдут плохие вещи.

Если вы часто делаете одно и то же, вы можете использовать идиому «выполнить вокруг». К сожалению, синтаксис Java является многословным, поэтому есть много более смелых табличек.

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

, где

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

Более сложный пример, например, исключения для переноса.

2 голосов
/ 05 октября 2012

Прошло много времени, но с Java 7 был добавлен оператор try-with-resources вместе с интерфейсом AutoCloseable .

2 голосов
/ 26 сентября 2008

Самое близкое, что вы можете получить в Java, это попробовать / наконец. Кроме того, Java не предоставляет неявный тип Disposable.

C #: определение области за пределами блока использования

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: область видимости переменной вне блока

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 #: определение области внутри блока

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: определение области внутри блока

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

}
2 голосов
/ 26 сентября 2008

Не то, чтобы я знал. Вы можете что-то симулировать с помощью блока try ... finally, но он все равно не совсем тот.

1 голос
/ 26 сентября 2008

Я думаю, что вы можете достичь чего-то похожего на блок "using", реализуя анонимный внутренний класс. Как Spring делает с «Шаблонами Дао».

0 голосов
/ 01 февраля 2009

Фактическая идиома, используемая большинством программистов для первого примера, такова:

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

Использование этой идиомы требует меньше отступов, что становится еще более важным, если у вас есть более 2 ресурсов для очистки.

Кроме того, вы можете добавить в структуру предложение catch, которое будет обрабатывать новое исключение FileStream (), если вам это нужно. В первом примере вам понадобится еще один включающий блок try / catch, если вы хотите это сделать.

0 голосов
/ 07 октября 2008

Если мы получим BGGA-замыкания в Java, это также откроет для подобных структур в Java. Gafter использовал этот пример в своих слайдах, например:

withLock(lock) { //closure }
0 голосов
/ 27 сентября 2008

Ну, в любом случае, использование было синтаксическим сахаром, так что ребята из Java, не переживайте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...