Есть ли в java эквивалент предложения C # “using”
Вопрос
Я видел ссылку в некоторых опубликованных на 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".