Аналог using в java

Есть ли в Java эквивалент C# «using» предложение?

Я видел ссылки в некоторых опубликованных на C# вопросах на предложение «using». Есть ли у Java аналог?

с java 7 ответ изменился с нет на да

Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше.

Управление транзакциями JDBC — это мощная функция, которая позволяет рассматривать группу операций с базой данных как единую единицу работы. Оно.

WebClient — это реактивный веб-клиент, представленный в Spring 5. Это реактивное, неблокирующее решение, работающее по протоколу HTTP/1.1.

Ответы 12

да. В 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 <. >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

Можно ли обновить этот ответ примером C# с его блоком using, а затем Java с помощью try-finally? Предпочтительно пример, который использует 2 отдельных ресурса, чтобы мы могли задокументировать, как убедиться, что все закрыто правильно.

Как парню, занимающемуся Java, приведенное выше сравнение довольно болезненно.

Хотя технически правильный, этот шаблон «попробуй / наконец» не самый лучший. Использование: X x = new X (); попробуйте finally

Если, конечно, new X () не генерирует исключения, такие как FileNotFoundException, в этот момент вам нужно либо ввести другой уровень try-except, либо использовать вышеуказанное и обработать FileNotFoundException, используя существующую попытку. Ни один из вариантов не особо приятен.

Нет блока захвата. Если «new X ()» вызывает исключение, для «X x» ничего не будет выделено, поэтому нет необходимости проверять, является ли он нулевым. Вы никогда не дойдете до конца.

Макдауэлл прав. Если ваши выделения сбрасываются, то в блоке finally нечего делать. Вы это понимаете. Вы просто не понимаете, что понимаете это. 🙂 Ваши проверки на null должны обойти тот факт, что ваши выделения находятся в неправильном месте.

Оглядываясь назад, я согласен с отделением обработки исключения FNF от обеспечения закрытия потока. Даже если для этого потребуется еще один внешний блок try . catch или объявление throws.

Этот код сейчас даже не компилируется. Все, что используется в блоке finally, должно быть объявлено вне блока try.

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

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

Бедный @shifoz! Вы, ребята, жестоки. Вопрос был совершенно расплывчатым, и он мог иметь в виду этот msdn.microsoft.com/en-us/library/sf0df423(VS.80).aspx . Шифоз, вы можете восстановить некоторые очки, спросив что-нибудь о программистах, например: «Какой у вас любимый цвет программирования в RGB?»

public void func() < < ArrayList l = new ArrayList(); >System.out.println("Hello"); > 

Это дает вам ограниченную область применения предложения using, но нет интерфейса IDisposable для вызова кода завершения. Вы можете использовать try <> catch () <> Наконец <>, но в нем нет сахара в использовании. Между прочим, использование финализаторов в Java — вообще плохая идея.

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

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

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

Источник

C# vs Java: Using

Отталкнемся от директивы/оператора using в C# и посмотрим что там есть в Java.

Директива / Оператор using

Импорт типов

using позволяет использовать типы описанные в других пространствах имен без указания fully-qualified-name

using MyApplication.MyPackage; // . var myClass = new MyClass(); 

тут мы можем использовать myClass не указывая молный путь к классу MyApplication.MyPackage.MyClass

Псевдонимы

Псевдонимы можно создавать для пространства имен или конкретных типов как показанно ниже

using MyPackageAlias = MyApplication.MyPackage; // or for type alias using ClassToUse = MyApplication.MyPackage.MyClass; 

С помощью using можно сделать псевдоним на параметризированный generic:

using IntListAlias = Listint>; //. var list = new IntListAlias(); list.Add(42); 

Глобальный импорт через using

  • Действие using распространяется на текущий файл.
  • using может быть объявлен в начале файла или в начале пространства имен.

С помощью global , сделав только одно объявление, можно импортировать содержимое пространства имен во всех файлах проекта.

global using MyApplication.MyPackage; 

Содержимое покате MyPackage будет импортировано во все файлы проекта.

Глобальный импорт через файл проекта

Другой способ глобально подключить пространство имен — это файл проекта.

.  Include="MyApplication.MyPackage" /> . 

Импорт статических членов классов

В случае когда наш тип MyClass содержит статические члены или вложенные типы — мы можем импортировать только их и использовать их без указания типа MyClass .

// for class namespace MyApplication.MyPackage  class MyClass  static int Add(int a, int b)  return a + b; > > > // we can use it as using static MyApplication.MyPackage.MyClass; // . var sum = Add(1, 2); 

Аналогично для вложенных типов.

Еще пример из документации:

using static System.Console; using static System.Math; class Program  static void Main()  WriteLine(Sqrt(3*3 + 4*4)); > > 

Wildcard Imports

Если мы пишем using MyApplication.MyPackage; — это значит что мы делаем доступными все типы из пространства имен MyApplication.MyPackage . Такое поведение вполне точно описывает что мы подразумеваем под wildcard imports когда в Java пишем import MyApplication.MyPackage.*; . Получается, что wildcard imports для using в C# — это поведение по умолчанию.

Важно отметить что в C# мы не можем импортировать конкретный тип c using name

using MyApplication.MyPackage.MyClass; // incorrect 

такое возможно только с использованием алиаса

using MyClassAlias = MyApplication.MyPackage.MyClass; // correct // or with same name using MyClass = MyApplication.MyPackage.MyClass; // correct 

но такой подход уже выглядит как будто мы делаем что-то не правильно.

Инструкция using и IDisposable

Как это работает?

using в C# может использоваться как оператор для автоматического закрытия объектов имплементирующих IDisposable.

string txt = String.Empty; using (StreamReader sr = new StreamReader(filename))  txt = sr.ReadToEnd(); > 

В этом примере при входе в блок using будет создан поток StreamReader , а при выходе этот поток будет закрыт посредствам вызова метода Dispose() у StreamReader .

  • using похож на try-with-resources в Java.
  • await using используется для IAsyncDisposable
  • в using можно передать объект сласса имплементирующего IDisposable
var reader = new StringReader(manyLines); using (reader)  . > 
using (StringReader left = new StringReader(numbers), right = new StringReader(letters))  . > 

IDisposable Interface

Интерфейс для реализации освобождения неуправляемых ресурсов.

Стоит быть аккуратных, возможны проблемы если метод Dispose не будет вызван и ресурсы не будут освобождены. Как решение этой проблемы документация предлагает следующее:

Because the IDisposable.Dispose implementation is called by the consumer of a type when the resources owned by an instance are no longer needed, you should either wrap the managed object in a SafeHandle (the recommended alternative), or you should override Object.Finalize to free unmanaged resources in the event that the consumer forgets to call Dispose.

IAsyncDisposable Interface

Интерфейс для реализации асинхронного освобождения неуправляемых ресурсов.

А что там в Java?

Все немного похоже и немного другое чем в C#. Аналог для using директивы — это import. А для using оператора — это try-with-resources.

Рассмотрим далее подробнее.

import как аналог using

Импортировать тип из другого пакета можно так

import MyApplication.MyPackage.MyClass; // . var x = new MyClass(); 

тут стоит заметить что мы импортируем не все содержимое пакета, а конкретный тип.

Импорт статических членов классов

В Java мы можем импортировать статический член используя import static

import static MyApplication.MyPackage.MyClass.staticMethid; 

это даст нам возможность использовать функцию staticMethid в коде текущего файла без указания имен пакета и класса.

import static java.lang.Math.cos; import static java.lang.Math.PI; double r = cos(PI * theta); 

Глобальный импорт как c global using

Wildcard Imports

Такой подход в Java будем считать не самым лучшим выбором при написании кода, так как используя это:

import MyApplication.MyPackage.*; 

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

Поэтому, в Java подход по умолчанию — это импорт только нужного типа вот так:

import MyApplication.MyPackage.MyClass; 

try-with-resources

Как это работает?

В Java try (если он with-resources) умеет «закрывать» объекты. Совсем как using в C#.

Мы можем использовать объект, реализующий интерфейс AutoCloseable , как приведено ниже. try в этом случае, помимо своей обычной работы по контролю за исключениями, вызовет метод close() для освобождения ресурсов в конце работы своего блока.

try (PrintWriter writer = new PrintWriter(new File("test.txt")))  writer.println("Hello World"); > 

AutoCloseable Interface

Все как в C# для IDisposable только в Java и для AutoCloseable и название метода другое.

An object that may hold resources (such as file or socket handles) until it is closed. The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header.

Conclusion

Мне показалось что в C# с using больше способов выстрелить себе в ногу. Возможно это из-за:

Источник

Читайте также:  Print to printer with php
Оцените статью