Есть ли в java эквивалент предложения C # “using”

StackOverflow https://stackoverflow.com/questions/141241

  •  02-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

ДА.Java 1.7 представила попробуйте-с-ресурсами конструкция, позволяющая вам писать:

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{ ...} наконец - то { ...}.В 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();
}

Другие советы

Да, начиная с 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 этот ответ и этот ответ.

Ближайшим эквивалентом в этом языке является использование 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;
}

Если получение находится в пределах блока "Попытка", вы освободите его в случае сбоя получения.В некоторых случаях вам, возможно, удастся обойти ненужный код (обычно тестирование на null в приведенном выше примере), но в случае, скажем, 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();
    }
}

Более сложный пример - это, например, перенос исключений.

Насколько мне известно, нет.Вы можете немного смоделировать с помощью блока try ...finally, но это все равно не совсем то же самое.

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

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

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

}

Это было долгое время, но с Java 7 инструкция try-with-resources был добавлен вместе с Закрываемый в автоматическом режиме интерфейс.

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

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

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

withLock(lock) { //closure }

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

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, если бы вы хотели это сделать.

Нет, это не так.

Ты можешь

public void func(){

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

}

Это дает вам ограниченную область действия предложения using, но нет никакого IDisposable интерфейса для вызова кода завершения.Вы можете использовать try{}catch(){}Finally{}, но в этом нет смысла использовать.Кстати, использование финализаторов в Java, как правило, плохая идея.

Нет, в Java нет using, наиболее похожей функциональностью является ключевое слово "import".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top