У овом упутству ћемо научити о изјави три-витх-ресоурцес за аутоматско затварање ресурса.
try-with-resources
Саопштењу се аутоматски затвара све ресурсе на крају изјаве. Ресурс је објекат који се затвара на крају програма.
Његова синтакса је:
try (resource declaration) ( // use of the resource ) catch (ExceptionType e1) ( // catch block )
Као што се види из горње синтаксе, изјаву изјављујемо try-with-resources
,
- декларисање и инстанцирање ресурса унутар
try
клаузуле. - навођење и руковање свим изузецима који могу настати приликом затварања ресурса.
Напомена: Извјештај три-витх-ресоурцес затвара све ресурсе који имплементирају интерфејс АутоЦлосеабле.
Узмимо пример који спроводи try-with-resources
изјаву.
Пример 1: пробајте са ресурсима
import java.io.*; class Main ( public static void main(String() args) ( String line; try(BufferedReader br = new BufferedReader(new FileReader("test.txt"))) ( while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) ) )
Излаз ако датотека тест.ткт није пронађена.
ИОЕкцептион у блоку три-витх-ресоурцес => тест.ткт (Нема такве датотеке или директоријума)
Излаз ако је пронађена датотека тест.ткт.
Унос блока три-витх-ресоурцес Лине => тест линија
У овом примеру користимо инстанцу БуффередРеадер за читање података из test.txt
датотеке.
Декларирање и инстанцирање БуффередРеадер-а унутар try-with-resources
израза осигурава да је његова инстанца затворена без обзира на то да ли се try
израз довршава нормално или баца изузетак.
Ако се догоди изузетак, њиме се може руковати помоћу блокова за руковање изузецима или кључне речи тхровс.
Потиснути изузеци
У горњем примеру, изузеци се могу избацити из try-with-resources
изјаве када:
- Датотека
test.txt
није пронађена. - Затварање
BufferedReader
објекта.
Изузетак се такође може избацити из try
блока јер читање датотеке у било које време може из многих разлога пропасти.
Ако се изузеци избацују и из try
блока и из try-with-resources
израза, изузетак из try
блока се баца и изузетак из try-with-resources
израза се сузбија.
Преузимање потиснутих изузетака
У Јави 7 и новијим, потиснути изузеци се могу добити позивањем Throwable.getSuppressed()
методе из изузетка који је бацио try
блок.
Ова метода враћа низ свих потиснутих изузетака. Потиснуте изузетке добијамо у catch
блоку.
catch(IOException e) ( System.out.println("Thrown exception=>" + e.getMessage()); Throwable() suppressedExceptions = e.getSuppressed(); for (int i=0; i" + suppressedExceptions(i)); ) )
Предности коришћења три-витх-ресоурцес
Ево предности коришћења три-витх-ресоурцес:
1. коначно блок није потребан за затварање ресурса
Пре него што је Јава 7 представила ову функцију, морали смо да користимо finally
блок како бисмо осигурали да је ресурс затворен како би се избегло цурење ресурса.
Ево програма који је сличан примеру 1 . Међутим, у овом програму користили смо коначно блок за затварање ресурса.
Пример 2: Затворите ресурс помоћу блока коначно
import java.io.*; class Main ( public static void main(String() args) ( BufferedReader br = null; String line; try ( System.out.println("Entering try block"); br = new BufferedReader(new FileReader("test.txt")); while ((line = br.readLine()) != null) ( System.out.println("Line =>"+line); ) ) catch (IOException e) ( System.out.println("IOException in try block =>" + e.getMessage()); ) finally ( System.out.println("Entering finally block"); try ( if (br != null) ( br.close(); ) ) catch (IOException e) ( System.out.println("IOException in finally block =>"+e.getMessage()); ) ) ) )
Оутпут
Унос покушај блок Лине => линија из датотеке тест.ткт Унос коначно блок
Као што видимо из горњег примера, употреба finally
блока за чишћење ресурса чини код сложенијим.
Приметили сте и try… catch
блок у finally
блоку? То је зато што се ан IOException
може догодити и приликом затварања BufferedReader
инстанце унутар овог finally
блока, тако да се и он хвата и њиме се рукује.
try-with-resources
Изјава се аутоматски управљање ресурсима . Не морамо изричито затварати ресурсе јер их ЈВМ аутоматски затвара. Ово чини код читљивијим и лакшим за писање.
2. пробајте са ресурсима са више ресурса
У изјави можемо пријавити више ресурса тако што ћемо try-with-resources
их одвојити тачком и зарезом;
Пример 3: покушајте са више ресурса
import java.io.*; import java.util.*; class Main ( public static void main(String() args) throws IOException( try (Scanner scanner = new Scanner(new File("testRead.txt")); PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) ( while (scanner.hasNext()) ( writer.print(scanner.nextLine()); ) ) ) )
Ако се овај програм изврши без генерисања изузетака, Scanner
објект чита линију из testRead.txt
датотеке и записује је у нову testWrite.txt
датотеку.
Када се направи више декларација, try-with-resources
изјава затвара ове ресурсе обрнутим редоследом. У овом примеру се PrintWriter
објекат прво затвара, а затим Scanner
се затвара.
Побољшање Јава 9 са искуством
У Јави 7 постоји ограничење на try-with-resources
изјаву. Ресурс треба декларисати локално у оквиру свог блока.
try (Scanner scanner = new Scanner(new File("testRead.txt"))) ( // code )
Да смо извор прогласили изван блока у Јави 7, генерисао би поруку о грешци.
Scanner scanner = new Scanner(new File("testRead.txt")); try (scanner) ( // code )
Да би се носила са овом грешком, Јава 9 је побољшала try-with-resources
израз тако да се референца ресурса може користити чак и ако није декларисана локално. Горњи код ће се сада извршити без грешке у компилацији.